Question Type Branching Rule
From EpiHandy
Contents |
Advanced Branching and Formula Function Described
A new formula function has been added to EpiHandy. This functionality is and extention of Pascal Ganaye\’s dotneteval library and Thomas Smith\’s ScratchPad calculator. The core functionality of these two components has been kept most as they were, with some minor additions to accomodate special requirements of EpiHandy.
This function can be used in the IF part of a branching, in numeric validation or in a calculated value. When using in the IF part of a branching and numeric validation it is important to create a formula that can evaluate to either True or False, comparison operators or a boolean result is thereby required.
It supports
- Boolean operations (and, not, or) \*Note not must be used on the form not(value)
- Comparison operations (= ,<, >, <>, >= ,<=)
- Common priorities (2+3\*5 return 2+(3\*5)=17
- Mathematical functions (i.e. +,-,/,\*,%,mod,x2,xn etc)
- Numbers, dates, strings, objects
- Access to question variable values and properties (i.e. $var1 and $var1$IsEnabled)
- Access to selected question manipulations (i.e. enable,disable,lock,unlock,hide,show etc).
- A number of functions (i.e. sin,cos,max,random,conversion etc.)
- Logical expression including if statements
- Conversion from one object type to another (i.e. Number to boolean - toBoolean)
Conceptual principles
A branching rule has 4 components: 1. A precondition for determining if it should be run 2. A logical expression that evaluates to true or false 3. A listing of actions to take if expression evaluates to true 4. A listing of actions to take if expression evaluates to false.
A question has an initial state (i.e. visible, enabled, etc), that state can only be changed with a branching rule.
A branching rule changes the state of a question. The problem occurs if two or more branching rules has an effect on a certain state of a particular question.
i.e. rule 1, says if x=2 then hide y else show y, at the same time rule 2 says if a=3 then show y else hide y. These two rules will have different effects on the same question. What state y will have depends on in which of the rules have been run last. The rules run based on listening to the edited event of a question.
i.e. edit x = 2 y = hidden edit a = 3 y = visible edit x = 4 y = visible edit x = 2 y = hidden
a better option here is to create one branching rule like a pre-condition for question y where if x=2 and a=3 then hide y else show y
An important advice for branching is to make a branching chart (based on nodes) to visualize the branching or document path to more easily understand the branching functions required.
Branching and Validation
To use the new branching function simply add a new question and select Branching Rule as the question type. You will then get a property pane similar to the displayed image.Section 1. is the precondition determinining if the rule should be run and has 4 alternatives.
- After any referenced variables are changed
This will automatically run the rule if any of the questions used in the expression has been changed. i.e if expression is like $a = $b, then the rule will be run after question a or b has been changed.
- After the previous question has been edited
This will run the rule when the previous question (in the form) has been edited.
- After one of the listed questions has been edited (i.e. $var1, $var2)
This allows you to list the questions that would run the rule when edited.
- After the following condition (i.e. $var1$IsEdited AND $var2$IsEdited)
This function allows you to do a complex precondition using an expression similar to that used in the IF expression. If this expression evaluates to true then it will run the rule.
The important part to understand is that in the textbox below 2.IF is where one should write a logical expression or function that evaluates to either true or false. The actual syntax etc is described later below.
The next part is the 3. THEN and 4. ELSE parts of the branching rule. if the formula in 1.IF evaluates to true, the actions defined in 3. THEN will be performed, if false, then it will perform actions defined in 4. ELSE.
Upto 10 actions can be defined per branching rule, initially only 2 are selected, you may select from 0 to 10 action elements and each of these can do it\’s actions on any number of questions.
The possible actions are:
- Disable
- Enable
- Hide
- Show
- Lock
- UnLock
- Set Mandatory
- Set Optional
- Skip (Disable)
- Skip (Hide)
- Reset
- Run Functions
- Show
- Message
Listing of variables
In the list of variables, you may list variables delimited with comma, space, colon, semicolon or tab on one of these forms: var1, var2, var3 $var1, $var2, $var3 $\{var1\}$, $\{var2\}$, $\{var3\}$ or a mixture i.e. var1; $var2: $\{var3\}$
Example
As an example we will use a form with 5 questions
- $var1 How old are you? (Numeric)
- $var2 How old were you when you got married? (Numeric)
- $var3 What is your birthdate? (date)
- $var4 What date did you marry? (date)
- $var5 Please state gender. (radiobuttons)
- male
- female
- other, specify (text)
- $var6 Are you pregnant? (radiobuttons)
- yes
- no
- $var7 Is your wife pregnant? (radiobuttons)
- yes
- no
- $var8 When is the expected delivery date? (date)
- $var9 How long have you/she been pregnant, number of months? (numeric)
Examples
| Calculate number of years at time of marriage: | $var1-$var2 | |
| Check if minimum 12 years at time of marriage | if($var1-$var2>12,true,false) | |
| Calculate age at time of marriage based on dates | GetAgeInCompleteYears($var4-$var3,now) | |
| To use a textual answer as a number (if not using numeric input type) | ToInt($varX) |
List of functions and calls
This is a list of function calls that can be used together with the calculations.
| Abs(val Double) Double |
| ACos(v Double) Double |
| ASin(v Double) Double |
| ATan(v Double) Double |
| ChCR() String |
| ChCRLF() String |
| ChLF() String |
| Chr(c Integer) String |
| Convert_Boolean_To_Integer(val Boolean) Integer |
| Convert_Boolean_To_String(val Boolean) Integer |
| Convert_DecimalToString_No_Zero(val Decimal) String |
| Convert_Integer_To_String_No_Negative_zero(i Integer) String |
| Convert_Integer_To_String_No_zeros(i Integer) String |
| Convert_String_To_Decimal(text String) Decimal |
| Convert_String_To_Integer(str String) Integer |
| Cos(v Double) Double |
| Date(year Integer, month Integer, day Integer) DateTime |
| Day(d DateTime) Integer |
| DbNull() System.DBNull |
| Dec(value Object) Double |
| degreesToRadians(degrees Double) Double |
| Entry(n Integer, s String, delim String) String |
| Exp(base Double, pexp Double) Double |
| Factorial(n Double) Double |
| FileExists(f String) Boolean |
| FileInfo(f String) IO.FileInfo |
| FindAge(birthDate DateTime) Age |
| FindAge(birthDate DateTime, reference DateTime) Age |
| FindBirthDate(reference DateTime, years Integer, months Integer, days Integer) DateTime |
| FindBirthDate(years Integer, months Integer, days Integer) DateTime |
| FloorDecimal(value Decimal) Decimal |
| Format(value Object, style String) String |
| Format_date(d DateTime, fmt String) String |
| GetAgeInCompleteMntsAndYrs(mnts Decimal) Age |
| GetAgeInCompleteMntsAndYrs(startdate Date, enddate Date) Age |
| GetAgeInCompleteMonths(startdate Date, enddate Date) Integer |
| GetAgeInCompleteYears(startdate Date, enddate Date) Integer |
| GetAgeInMonths(startdate Date, enddate Date) Decimal |
| GetAgeInTotalDays(startDate Date, enddate Date) Integer |
| GetDateAndTimeFromString(datestring String) Date |
| GetDateAndTimeString(d Date) String |
| GetDateAndTimeString_SQL(d Date) String |
| GetDateFromString(datestring String) Date |
| GetDateFromStringNoDefault(datestring String) Date |
| GetDateString(d Date) String |
| GetDateString_SQL(d Date) String |
| If(cond Boolean, TrueValue Object, FalseValue Object) Object |
| Index(s String, search String, delim String) Integer |
| Inlist(search String, list String, delim String) Boolean |
| Int(value Object) Integer |
| LeftTrim(str String) String |
| Len(str String) Integer |
| Long_date(d DateTime) String |
| Lower(value String) String |
| Max(v1 Double, v2 Double, _) |
| Min(v1 Double, v2 Double, _) |
| Mod(x Double, y Double) Double |
| Money(d Object) String |
| Month(d DateTime) Integer |
| Now() DateTime |
| PadLeft(str String, wantedlen Integer, addedchar String) String |
| Pi() Double |
| Power(v Double, e Double) Double |
| PowerDecimal(Value Decimal, power Integer) Decimal |
| Public ReadOnly Property E() Double |
| radiansToDegrees(radians Double) Double |
| Replace(base String, search String, repl String) String |
| RightTrim(str String) String |
| Rnd() Double |
| Round(value Object) Double |
| RoundSymArith(Value Decimal) Decimal |
| RoundSymArith(Value Decimal) Integer |
| RoundSymArith(Value Decimal, Decimals Integer) Decimal |
| RoundSymArith(Value Decimal, Digits Integer) Decimal |
| RoundSymArithToString(Value Decimal, Decimals Integer) String |
| Sin(v Double) Double |
| Sqrt(v Double) Double |
| strToMax(max Integer, str String) String |
| strToMax(str String, max Integer) String |
| Sum(pEnd Double, expression Double) Double |
| Sum(start Double, pEnd Double, expression Double) Double |
| Tan(v Double) Double |
| toBit(bol Boolean) Integer |
| toBit(no Integer) Integer |
| toBol(int Integer) Boolean |
| toBol(row DataRow, col String) Boolean |
| toBol_FalseTrue(int Integer) Boolean |
| toBol_FT(int Integer) Boolean |
| toBoolean(int Integer) Boolean |
| toBoolean(val Object) Boolean |
| toDate(str String) Date |
| toDate(val Object) Date |
| Today() DateTime |
| toDouble(str String) Double |
| toDouble(val Object) Double |
| toGuid(str String) Guid |
| toGuid(val Object) Guid |
| toInt(str String) Integer |
| toInt(t_f Boolean) Integer |
| toInt(val Object) Integer |
| toIntSex(male Boolean) Integer |
| Trim(str String) String |
| Trunc(value Double, prec Integer) Integer |
| TryCast(obj Object, tp System.Type) Object |
| Upper(value String) String |
| WCase(value String) String |
| WeekDay(d DateTime) Integer |
| Year(d DateTime) Integer |
List of variable actions
The following is a list of calls that will perform certain actions on the questions. NOTE! These are functions calls that return true or false depending on the success of the call. NOTE! The variable the call relates to must be quoted like this: SetEnabled(\’varname\’) and not like this SetEnabled(varname) or SetEnabled($varname), the two later will cause an error in evaluating the statements. Several calls like these can be made only separated by a space.
| Hide(varname String) Boolean |
| UnLock(varname String) Boolean |
| Show(varname String) Boolean |
| Lock(varname String) Boolean |
| Disable(varname String) Boolean |
| Enable(varname String) Boolean |
List of variable properties
The answer of any variable can be accessed by typing $ + variable name, i.e. $var1, $var2 etc. Further, for any variable it is possible to access extended properties of that answer by adding $ + property name, i.e.$var1$IsAnswered, $var1$TimeUsed Further, for any variable it is also possible to access any of the options i.e. for a question with alternatives i.e. sample question: $var5, Please state gender. (radiobuttons), which has options a: Female and b: Male, c: other, specify. For those you may access the state of those options like this: $var5$a or $var5$b (which returns true or false, for checked or not), or find i.e. specified value through $var4$c$SpecifiedValue or $var4$c$Specified (just to check if it has been specified).
The list of question and option specific calls are listed below:
| Question | Checked | Return the varname of the selected option (if single select)
NOT YET IMPLEMENTED |
| Question | CountChecked | Number of options selected |
| Question | CountRows | Number of rows in a datatable |
| Question | CountSpecified | Number of options specified |
| Question | DateTime | Date and Time last edited |
| Question | Guid | Uniqueidentifier of this answer |
| Question | IsAgeBased | Defines if date is based on age |
| Question | IsAnswered | Question answered status |
| Question | IsCalendarBased | Defines if date is based on calendar |
| Question | IsDateBased | Defines if date is based on a date |
| Question | IsDateNotKnown | Date is unknown |
| Question | IsDayApproximate | Day of date is approximated |
| Question | IsEnabled | Question is enabled |
| Question | IsLocked | Question is locked |
| Question | IsMandatory | Question is mandatory |
| Question | IsMonthApproximate | Month of date is approximated |
| Question | IsOpened | Question has been opened |
| Question | IsSaved | Question has been saved |
| Question | IsVisible | Question is visible |
| Question | NotApplicable | Question is not applicable |
| Question | NotKnown | Question is not possible to answer |
| Question | Options | List of question options.
NOT YET IMPLEMENTED |
| Question | Options_Selected | List of options selected.
NOT YET IMPLEMENTED |
| Question | Options_Specified | List of options specified.
NOT YET IMPLEMENTED |
| Question | Parent | The value of the parent question (if in a subform, else not useable. |
| Question | SpecifiedValue | The specified value of an option. Only relevant for single select lists.
NOT YET IMPLEMENTED |
| Question | Status | Numeric representation of status flag field. |
| Question | Text | The text of the question (as displayed) |
| Question | Timeused | The time this question was open for editing in secconds. |
| Question | Type | The type of question |
| Question | ValidationFailed | Question validation failed |
| Question | Varname | Question variable name |
| Option | Checked | Option is checked |
| Option | HelpText | The help text of the option |
| Option | Itemno | The item selected i.e. radiobuttons |
| Option | Specified | Option is specified |
| Option | SpecifiedValue | The specified value of this option |
| Option | Status | Numeric representation of status flag field. |
| Option | Text | The text of the option (as displayed) |
| Option | VarCode | The code of the option |
| Option | VarName | The concatinated variable name of the option. consisting of question + _ + option codes. i.e. var1_b |