Language glossary

Loops

To iterate over a set of items, or to repeat steps a pre-set number of times, this syntax is used:

     For x = 1 to y
             StuffHere()
     EndFor

Conditional execution

If statement

Simple conditional execution is wrapped in IF/ELSE/ENDIF keywords:

If x = 1
        StuffHere()
Else
        StuffThere()
EndIf

Multiple conditions: Case statement

Multiple evalution of conditions is wrapped in a DO CASE/CASE/OTHERWISE/ENDCASE statement. Only the first matching case is executed, no break statement (like in JavaScript) is necessary:

Do Case
        Case Age = 1
                StoreAnswer('AgeGroup', 1)
        Case InList(Age, 2, 4)
                StoreAnswer('AgeGroup', 2)
        Otherwise
                StoreAnswer('AgeGroup', 3)
EndCase

Functions

Abs(number)

Returns absolute value of a number

X = Abs(-1)
AdhocMailingColumn(number)

Returns the content of the column that was uploaded when inviting this respondent. If the respondent was not invited using the system, the result of this function will be empty.

AdhocMailingColumn(1) * will return the first column that was uploaded additionally to the email address

see also: See also mailing

Alltrim(string)

Removes leading and trailing characters from a string

AnswerTime(question)

Time it took for the respondent to answer a question (skip a screen in case of more than 1 question). The script belows checks the response time for Q2, and if more than 60 seconds send the respondent to a term screen (note: this could also be accomplished with a routingpoint)

If AnswerTime('Q2') > 60
        RenderObj.GotoItem = 'TermTooSlow'
EndIf
Asc(character)

Returns the numeric value of a character

DC.AssignPassword(forcenew)

Assigns a password to a respondent. Then forcenew is set to .t. ,it will generate a new password in case a password already exists

At(substring, string)

Returns the location of a character in a string

X = At('b', 'abc') && x is now 2
Between(variable, min, max)

Checks if a numeric value is between two extremes, including the extremes

X = Between(5, 1, 10) && x is now true
BufferAnswer(item, answer)

Pre-fills an answer so the respondent sees the checkbox checked, but does not actually store this answer yet.

BufferAnswer('Q1', 1)
Chr(asciivalue)

Returns the character value of a number

X = Chr(65) && X is now 'A'
ContentFromKeyfile(filename, key, index)

Returns the content of a row in an uploaded file with key/value pairs. The file must be uploaded in the projects private folder projectname/private/keyfile.txt and must contain keys (such as postal codes) and values (such as province or regions) separated by tabs. For example:

1017AA Amsterdam West 5021AA Tilburg South

X = ContentFromKeyfile('Postalcodes.txt', '1017AA', 1)
# X now has value 'Amsterdam'
Y = ContentFromKeyfile('Postalcodes.txt', '1017AA', 2)
# X now has value 'West'
CountAny(question, min, max)

Counts the number of answers in a singleresponse/multiplesubjects battery that lies between certain values

* Counts the number of answers between 3 and 5, for instance
* decoding 'satisfied' to 'very satisfied':
x = CountAny('Q', 3, 5)
CrossLineLevel(question)

Determines a number between 0 and 1 indicating in how far a Christmas-tree pattern is present in the answers of a single response/multiple subjects question

Date()

Returns the current date

X = Date()
Dow(date)

Returns the day of week

X = DOW(Date())
Empty(variable)

Checks if a value is empty:

X = ''
If Empty(x)
        StoreAnswer('MyVar', '')
EndIf
Evl()

Returns the first non-empty value:

X = Evl(Q1, 3)
* X has now the value of Q1 or, in case Q1 is empty, the value 3
ExtAnswer(questionidentifier)

Returns the external answer

X = ExtAnswer('IntakeProfileQuestionnaire.Age')
ExtractXML(content, tag, default)

Extracts a value from xml

content = '<firstname>Robert</firstname><lastname>van Geel</lastname>'
Y = ExtractXML(content, 'firstname') && Y is now 'Robert'
Z = ExtractXML(content, 'middlename', 'Unknown') && Z is now 'Unknown'
GenPWD([length])

Generates a random string of [length] characters. Default length is 6.

X = DC.GenPWD(6)
GetBestLSMatch(content, target, max, returntype, cost)

Gets the best match based on Levenshtein algorithm. Assumes a question ‘Brands’ that contains software brands. This example checks the mistyped word Microsoft agains the brands table (eg Oracle, Microsoft, Sun).

Returntype = 1: returns the text (eg ‘microsoft’) Returntype = 2: returns the numer of the found answer (eg 2)

X = GetBestLSMatch('microsft', 'Brands', 1, 1)
GetEligibleCells(mask, targetvar[, number_to_punch][, '%'])

This function name is obsolete

See SelectCells

SelectCells(mask, targetvar[, '%'][, number_to_punch][, ordermask][, orderedpunches][, prios][, exclusions])

Iterates through all of the cells that match the first parameter, which is a cell mask. Then punches into CellTarget the number of cells that are applicable to this respondent based on prioritization (either least-filled absolute, or least-filled percentually).

The orderedmask and orderedpunches are optional additional parameters that drives a second selection. This second step takes the output of the first and feeds it into a second list of cell counters, so that the cells that were selected in the first step are now also balanced by ‘first shown’, ‘second shown’ etc.

By example:

SelectCells('CellUK*', 'AssignedConcept', '%', 2)

This function call will store 3 values in MyPunches by taking these steps:

  • take all the cells that match the name CellUK*

  • find out for which cells the respondent is eligible and makes a list bast on least-filled. It does this by evaluating the expresssions.

  • store two selected cells in variables AssignedConcept_1 and AssignedConcept_2, in order of least filled-to-most-filled

Example of cell definitions:

CellUKAge1Concept1 => AgeGroup = 1 and (EligibleChecking or (AssignedConcept = 1))
CellUKAge1Concept2 => AgeGroup = 1 and (EligibleChecking or (AssignedConcept = 2))
CellUKAge1Concept3 => AgeGroup = 1 and (EligibleChecking or (AssignedConcept = 3))
CellUKAge2Concept1 => AgeGroup = 2 and (EligibleChecking or (AssignedConcept = 1))
CellUKAge2Concept2 => AgeGroup = 2 and (EligibleChecking or (AssignedConcept = 2))
CellUKAge2Concept3 => AgeGroup = 2 and (EligibleChecking or (AssignedConcept = 3))

Note that the cells will actually ‘count’ the moment this respondent becomes a qualified complete. At this point in the questionnaire the respondent is either ‘eligible’ or not, meaning that based on his current answers so far (age, gender, etc.) he COULD fall into the given cell(s) on completion.

At this point in time we’re trying to decide the assignable value (eg the concept to show a respondent) so the value of AsssignedConcept is still empty. For that reason we need to ‘mute’ that part of the expression during the assignment procedure. This is done by using the EligibleChecking variable which indicates that the expression is run during a SelectCells call. Note that the ‘%’ in this call indicates that it will prioritize the cells based on least-filled percentage:

Note

The value that is punched will be inferred from the name of the punch-cell, by reading the rightmost numerical part of the cell name. That means that when the cell is named MyCellABC12, the system will punch a 12. This should match the expression of the cell:

MyCellABC12 => MyConcept = 12

When the number of punchable variables equals zero, the function returns the list instead of actually performing the punches. This way you can manipulate the list in your own script and perform punches manually:

SelectedConcepts = SelectCells('CellUK*', 'AssignedConcept', '%', 0)
* now you can manipulate x and manually punch:

* ... manipulation code goes here...

For Counter = 1 to 3
        StoreAnswer('AssignedConcept_' + alltrim(str(cnt)), SetItem(SelectedConcepts, Counter))
EndFor

In addition to the above you can add the ordermask and orderedpunches parameters:

myorder = SelectCells('CellUK*', 'AssignedConcept', '%', 1, 'Tot?Concept*', 'OrderedConcepts')
SetRandOrder('MyConceptBlock', myorder)
This will:
  • take all the cells that match the name CellUK*

  • finds out for which cells the respondent is eligible and makes a list bast on least-filled

  • store two selected cells in variables AssignedConcept_1 and AssignedConcept_2, in order of least filled-to-most-filled

  • then finds Tot1Concept* for the selected cells to find out which concept was shown least in the first position, and store that in OrderedConcepts_1

  • then finds Tot2Concept* for the selected cells to find out which concept was shown least in the second position, and store that in OrderedConcepts_2

the line SetRandOrder(‘MyConceptBlock’, myorder) will actually set the order to be used in the block randomization

To demonstrate the prios parameter, see the following syntax:

SelectCells('CellUK*', 'AssignedConcept', '%', 1, 'Tot?Concept*', 'OrderedConcepts', 'PRIO1;PRIO2')

This will have the effect that FIRST all cells with in the name PRIO1 will be selected and prioritized, THEN all cells with PRIO2 in the name and finally the rest of the cells.

You can use the exclusion parameter if you want to make sure two specific concepts are never selected at the same time for the same respondent. This can be relevant when, for instance, concepts are very similar. To demonstrate the exclusion parameter, see the following syntax:

SelectCells('CellUK*', 'AssignedConcept', '%', 1, 'Tot?Concept*', 'OrderedConcepts', '', '1!2 3,4!5,6')

This will interpret the parameter value 1!2 3,4!5,6 as follows:

  • it will, after prioritizing the concepts, go through all the selected number left-to-right

  • if concept 1 is selected encountered, it will strip out concept 2 from the remaining list

  • but if concept 2 is encountered, it will strip concept 1 from the remaining list

  • if concept 3 or 4 is encountered, it will strip out concepts 5 and 6 from the remaining list

  • but if concept 5 or 6 is encountered, it will strip out 3 and 4 from the remaining list

Request.GetIPAddress()

Returns the respondents current IP Address

StoreAnswer('IPAddress', Request.GetIPAddress())
GetListKey(code, keysource[, markused])

Checks to see if a certain key exists in the database. For instance if for 1 survey you want to allow only certain postal code you can upload these postal codes and check the respondents answer against these postal codes. When markused is passed, any found key will be marked as ‘used’ and will not be found the next time

x = GetListKey('mykey', 'handedoutkeys', .t.)
If Empty(x)
        * not a correct access key
EndIf
Request.GetParameter(parametername)

Returns a parameter from the link. Parameters ExtID, UI, U, L, D, K, testsession, I are handled automatically and reserved, you can not use those parameters for other purposes.

StoreAnswer('AgePunch', Request.GetParameter('passedage'))
GetRandOrder(question, type)

Retrieves the randomization order of a certain question. Type can be

  • ‘A’ for randomization of the answers

  • ‘S’ for the subjects

  • ‘B’ for the order of blocks

  • ‘C’ for the order of contexts (the secundary subjects in MRMS type questions)

&& for single response, the type parameter is optional since it has only a-randomisations:
X = GetRandOrder('Q1')
GetServerName()

Returns the hostname of the server for the current call (eg surveys.yourpanel.net or www.dotdata.nl)

GetWordCount(Sentence)

Returns the number of words in a string

X = GetWordCount('the fox jumped of the fence') && x now equals 6
GetWordNum(sentence, number)

Retrieves a word from a sentence

X = GetWordNum('the fox jumped of the fence', 3) && returns 'jumped'
ICase(condition, expression[, condidion2, expression2 ...][, default])

Immediate (one-liner) CASE. Handy for filters since filters are typically one-line expressions

ICase(YearBorn < 1900, 'very old', YearBorn < 1980, 'middle aged', 'young')
Iif(condition, expression, else_expression)

Immediate IF. Handy for filters since filters are typically one-line expressions. Comparable to ICase but limited to 1 alternative value

X = Iif(Yearborn < 1980, 'middle age', 'young')
ImgDir()

Current questionnaire-dependent path to image/upload folder that is connected to the questionnaire

X = IMGDir() && x now equals /img/projectname
ImgLangDir()

Current questionnaire-dependent path to image/upload folder that is connected to the questionnaire with a language-based subfolder

X = IMGLangDir()
* x now equals /img/projectname/3 for Dutch and /img/projectname/5 * for UK English
IncludeAudio(url_to_audiofile, width, height, autostart)

Includes an audio file in the questionnaire

IncludeAudio(IMGDir() + '/myaudiofile.mp3', 50, 50, t.)
IncludeFile(filename)

Includes an uploaded textfile into the questionnaire, path must be relative

IncludeFile('test.txt')
IncludeFlash(url[, with][, height])

Includes a flash file into the questionnaire

IncludeFlash(IMGDir() + '/myflashfile.swf', 500, 500)
IncludeFLV(url[, with][, height])

Includes a flv file into the questionnaire

IncludeFlash(IMGDir() + '/myflashfile.flv', 500, 500)
IncludeVideo(filename[, width][, height][, autostart][, buffertime, statusbar])
IncludeVideo(IMGDir() + '/myflashfile.flv', 500, 500)
InList(value, check1,[check2], [check3]…)

Check whether a value is in a list

If InList(Q1, 3, 5, 7) && When Q1 equals 3, 5 or 7…
        * Some code
EndIf
Int(number)

Integer value of a real number

X = Int(5.5) && x now equals 5
IsAlpha(character)

Checks if a character is alphanumeric

X = IsAlpha('ë') && x is now true
X = IsAlpha('1') && x is now false
Member.Join()

Undocumented, used for very specific purposes only

JustASCII([spaceunderscore][, allownumbers][, otherallowed])

Takes out all non-ASCII characters from a string and optionally replaces spaced with an underscore. Leaves out numbers unless allownumber is .t. When you want to allow other characters, pass them in otherallowed, eg ‘:/.’ when you want to compose a URL

X = JustASCII('http://www*&(.wikipedia.org') && x now equals http://www.wikipedia.org
JustDigits(string)

Extracts all numbers from a string:

X = JustDigits('EUR 123,00') && Returns 123
LargestVariable(set)

Returns the name of the variable with the largest value

X = LargestVariable('Q1;Q2;Q3')
Len(string)

Returns the length of a string

X = Len('hello') && x now equals 6
Levenshtein(str1, str2, costvalue)

Implements the Levenshtein algorithm, returns the relative distance between str1 and str2

LoadFile(filename)

Returns the content of an uploaded file

x = LoadFile('uploaded.txt')
Lower(string)

Transforms a string to lowercase

X = lower('aBcDe') && x now equals 'abcde'
MD5()

Returns an MD5 hash of a certain string. Excellent for hashing purposes, less so for security purposes

X = MD5('test') && x now equals 098F6BCD4621D373CADE4E832627B4F6
MergeQuestions(question1, [question2…, ]textfile[, usefilters])

Merges elements of questions into a custom uploaded html template.

MergeQuestion('Q1', 'Q2', 'merged.txt')

The content of the mergetext can be:

<script>
        var x=[1#1 __item__ 1#1];
        var y=[2#2 __item__ 2#2];
        var Age=[# Age #];
        var FirstName = '[# FirstName #]';
</script>

This means that tags [1#1 x 1#1] will be evaluated in the context of the first mergeable question, and [1#1 y 1#1] will be evaluated in the context of the second mergeable question.

Any regular [# #] tags will be evaluated in the general context, you can use this to pull in regular values for other variables, in the example above Age and (string variable) FirstName.

Mod(val1, val2)

Returns the remainder of a division

Occurs(str1, str2)

Returns the number of occurances of a string in a substring

X = Occurs(' abc' , 'abcdefabc' ) && x will now be 2
Odd(val)

Returns true if the passed value is odd

PAnswerHTML([questionlabel, ]optionno[, type])

This call is used to dynamically insert answertexts of single response items in templates. Optionno is the number of the answer-possibility, type can be: 1 for the plain text of the answer-possibility 2 for the clicker control 3 for the clickable text of the answer-possibility (a click triggers the related control to be checked) The advantage over using static texts in HTML files is that it provices a mechanism to let the program handle randomizations for texts. <# PAnswerHTML(’ Q1’ , 1) #>

PictureOption(urltopicture)

Inserts a picture as a clickable item as an answer-possibility

PopupPic(picture, smallwidth, height, width, caption[, picture2])

Inserts a picture that, when clicked, on pops up large. Original size is in smallwidth, the size of the popup is passed in height and width. Caption is the title of the popup. In case you want to use a different picture for the popped-up version you can pass it in picture2

PopupPicture('thumbnail.jpg', 10, 100, 100, 'see picture', ' large.jpg')
ProtectPicture(filename)

Inserts a one-time useable link to a temporary image and inserts no-cache directives. The client will now download the temporary picture, after which the picture is deleted. The picture will not remain in the cache on the respondents computer. Although not bullet proof, this makes saving pictures do disc more complicated for the respondent

Punch1On1(source, destination)

Copies all answers from one questionnaire to the other, provided that the questions have similar labels and structure. Used for tracking questionnaires when there’ s one ‘status questionnaire’ that contains the current answers of the latest complete

PunchQuota(cellname, condition)

Manually increases a quotumgroup. Handy when you want to count quotums for non-completes or unqulifieds or when you want script-control to quotumgroups.

Rand()

Returns a broken number between 0 and 1

RandomInt(max)

Returns a random integer between 1 and max

X = RandomInt(10) && any number between 1 and 10

RankVarsByValue(vars[, reverse])

Takes the inputvariables and returns them in order of small to large or, incase of reverse being true, from large to small:

Q1 = 3
Q2 = 4
Q3 = 1
X = RankVarsByValue('Q1;Q2;Q3') && x is now 'Q3;Q1;Q2'

Note

RankVarsByValue is a legacy function name, it’s much clearer to use functions SortVarsSmallToLarge and SortVarsLargeToSmall. They offer the same functionality but with more descriptive names.

SortVarsSmallToLarge(varlist):

Sorts the variables in the list based on their values, smallest variable in front.

SortVarsLargeToSmall(varlist)

Sorts the variables in the list based on their values, largest variable in front.

RollOverPic(PictureName, Content)

Roll over a picture

Round(Number)

Rounds a number

RunProtectedScript(scriptname)

Runs a script that is protected and hidden, eg because it contains a calculation method that should not be seen by the programmer or because it contains non-safe functions like out-of-scope file access. Scripts need to be approved and uploaded by system administrator.

RunProtectedScript('CalcSecretMethod')
SetRandOrder(item, type, order)

Sets the randomization order of an item. You need to set the ‘randomize’ property of the item, though:

Type=A:order of answer-possibilities Type=S: subjectsorder Type=C: contextorder Type=B:blockorder

SetRandOrder('Q1', 'A', '3;2;1')
* This sets the third answer-possibility first, the second as second and the first at the third position
SetTopGroup(set[, reverse])

Evaluates variables and returns the variable with the largest (in case of reverse: smallest) value. When more variables have this same value, it returns all of them.

Q1 = 1
Q2 = 1
Q3 = 2
Q4 = 3
X = SetTopGroup('Q1;Q2;Q3;Q4') && x now equals 'Q1;Q2'
SmallestVariable(vars[, norand])

Returns the variable with the smallest variable. When more than 1 variable has the same, lowest, value, it will return a random one unless norand is set to true

X = SmallestVariable('Q1;Q2;Q3')
Max(number1, number2 )

Returns the highest value of a set of values

X = Max(5,4,3,6,7,2) && x now equals 7
Min(number1, number2 )

Returns the lowest value of a set of values

X = Min(5,4,3,6,7,2) && x now equals 2
Mean(content):

Calculates the mean of the given list of values

X = Mean('1;2;3;2;1;4;5;4;3;2;1;2;3;4;5') && 2.8
Rotate(strname, numbermax[, instancestring])

Rotates any values, returning a number between 1 and numbermax. This number is remembered through the respondents session. For instance, if you want to number questions and you skip a question now and then, you may want to leave out all gaps in the question numbering so you don’t want to use a static number in the questiontext. However, if you’d click ‘back’ the system would have no way of knowing that it needs to show the previous value. Because of that, you can pass an instance string, meaning that if a rotation value was already assigned for this question, it will be pegged at the same value:

Question [# Rotate( ' rotation1', 3, 'firstquestion') #]:
do you ever buy flowers

--------------------------------------------------------------------

Question [# Rotate( ' rotation1', 3, 'secondconditionalquestion') #]
what kind of flowers

--------------------------------------------------------------------

Question [# Rotate( ' rotation1', 3, 'thirdquestion') #]
do you ever buy chocolate
SetQuotaValues(quotanames, newvalue)

Sets the value of one or more quota counters

SetQuotaValues('MyCounter', 1)
SetQuotaValues('MyCounter;MySecondCounter', 1)
SetQuotaValues('MyCounter*', 1) && supports wildcards
StdP(content):

returns the standard deviation based on population

X = StdP('1;2;3;2;1;4;5;4;3;2;1;2;3;4;5') && 1.32664991614
StdS(content):

returns the standard deviation based on sample

X = StdS('1;2;3;2;1;4;5;4;3;2;1;2;3;4;5') && 1.37321312465
StoreAnswer(varname, value)

Stores an answer by punching the value into the question:

StoreAnswer('Punch', 1)
StoreAnswerWhenNotEmpty(varname, value)

Like StoreAnswer, stores a value but only when the value is not empty. This is handy when, for instance you have a list of ‘product use’ values in a multiple response and only the ‘used’ values need to be punched through to another item, making the entire process more efficient since in these kind of scenarios there is no need to store empty values anyway.

MarkParticipationReady()

This function marks the respondent as qualified complete and increases the quota counters. However, the session is not cleared so the system can continue to feed and process follow-up items to the respondent. After that, once a normal endscreen is encountered, the session is cleared but the quota counters are not increased again.

TextLine(filename, value)
This function is used when you need lookup lists, typically regions that are containing a list of postal codes.
Suppose you have a set of postal codes like this:
district1=;11111;22222;33333;
district2=;4444;5555;6666;
district3=;7777;8888;8888;

What you can do now is the following:

  • upload the above as a file into the project ‘privatepostalcodes.txt’ - note that you may first need to make a subfolder ‘private’ first (The private subfolder ensures that the file cannot be read from the outside world, so anything that goes in subfolder ‘private’ is shielded from the public. This goes for all projects in all circumstances and is good practice, currently I think sometimes files are updated directly into the project root folder which means that even though they are just meant for the program, in principle they can be downloaded by the public)

Now you can in your code issue the following lines:

x = textline('postalcodes.txt', '5555')
if x = 'district2'
   storeanswer('districtfound', 2)
endif
So what the first line does, is:
  • opening the file that you uploaded

  • find the line that contains the searched value delimited with semicolons (in this case ‘;5555;’)

  • return the corresponding group name (in this case ‘district2’)

This way you only need one upload file and one function call. Note that this will also work:

x = textline('postalcodes.txt', 5555)

But this one is problematic:

x = textline('postalcodes.txt', 05555)

because in the end this will search for ‘;5555;’ and not ‘;05555;’ so searching by string value is recommended over numeric ones.

In case there are no ‘groupname=’ sections in the data, it just returns the line number, so you can also just upload:

;11111;22222;33333;
;4444;5555;6666;
;7777;8888;8888;

in which case the return value for the example above is just numeric 2:

x = textline('postalcodes.txt', '5555')
if x = 2
   storeanswer('districtfound', 2)
endif
Str()

Creates a string from a number

X = Str(1 + 1) && x will be 2
StrExtract(str, start[, end=start])

Extracts a text fragment from a text

X = StrExtract('abcdef', 'b', 'e') && x now contains 'cd'
StrTran(search, sought, replacement)

Replaces parts of a string with another string

X = Strtran('an apple and an egg', 'n apple', ' pear')
&& x is now 'a pear and and egg'
Substr(expression, start[, length])

Returns the substring of a certain string

X = Substr('abcde', 2, 2) && x is now 'bc'
SubjectHTML(question, option)

Returns the text of a subject for dynamic display in a template. See PAnswerHTML

SumProduct(leftlist, rightlist)

Multiplies each element at the left with the corresponding element at the right, and returns the result The result is comparable with the Excel function. Note that the input is typically a delimited string set.

X = SumProduct(';1;2;3;', ';0.1;0.2;0.3333;') && x is now 1.49999
TimePerAnswer(secondscutoff)

Average time per answer given. When the respondent pauses (eg longer than 15 minutes between 2 answers coming in), the answer doesn’t count for the average at the cutoff point. Note: more than 1 answer can be on 1 page (eg for single response/multiple subjects). Basically the number of answers divided by total response time. Clicking back and forth does not influence the number of answers even though strictly speaking the answers are now double present.

TimePerClick()

Average time per screen. Note: more than 1 answer can be on 1 page (eg for single response/multiple subjects) but this function corrects for that so you can see the number of screens submitted, not the number of answers. Also: when clicking back and forth, these clicks influence the average

ToolTip(text, tooltip[, class][, style])

Inserts a tooltip into the html-document of the respondent Move mouse <# Tooltip(’ this is a long description’, ‘here’ ) #> to see a description.

Track(varname)

Tracks changes in an answer in case the respondent clicks back and forth, changing his answer.

StoreAnswer('Tracked', Track('Q1'))
* stores ;abc;def; when the respondent first answered abc, then changed it to def
Upper(str)

Returns the string in uppercase

X = Upper(' hello') && x is now HELLO
UploadedExtAnswerString('Projectname.Varname')

Returns a value from an uploaded dataset that matches the current unique identifier or persid

X = UploadedExtAnswerString('MyProjectname.MyVarname')

The way to use this is by following the following steps:

  • Create a file ‘MyProjectname.txt’

  • Make sure the first line contains fieldnames

  • Make sure there is a field PERSID and/or UNIQUEID (not case sensitive)

  • follow the header line with data, like you would copy and paste it from Excel

  • that means it MUST be tab delimited

here is an example:

PERSID UNIQUEID Age
123 0 25
0 xxyyzz 32
  • create a folder ‘private’ inside your project

  • upload the file into this private folder

  • start your participations with &UI=xxyyzz

  • the syntax from the example now should lead to value X being ‘32’

  • note that the function always returns texts. If you want values you need to convert it using val(X)

URLDecode(url)

Recodes the url from encoded to human readable format. Reverse of URLEncode.

x = URLDecode('https%3A%2F%2Fwww%2Edotdata%2Enl')
* x is now https://www.dotdata.nl
URLENcode(encodedurl)

Encodes a url for use in an address bar or redirect.

x = UrlEncode('https://www.dotdata.nl')
* x is now https%3A%2F%2Fwww%2Edotdata%2Enl
Val(string)

Returns the value of a stringrepresentation of a number

X = Val('123' + '45' ) + 1 && x is now 12346
ValueOf(string)

Returns the value of a variable when the name of the variable is not determined at design time but at run time:

QuestionNo = 1
Varname = 'Q' + Alltrim(Str(QuestionNo + 1))
X = ValueOf(Varname) && x is now the value of variable Q2
Variance(content):

Calculates the variance of the given list of values

X = Variance('1;2;3;2;1;4;5;4;3;2;1;2;3;4;5') && 1.88571428571
VisibleSubjectsCount(question)

Returns the number of visible subjects for a question, after evaluation of all filters

hasipduplicates('Age;Gender;', 90)

This will look for respondents in the same study who have the same IP address as the current respondent AND who have the same answer to both questions Age and Gender. The first parameter can contain up to three variables, for instance ‘Age;Gender;Education’. The second parameter is the number of days the system should look back. In the above example, if the respondent at this IP address was already finishing the questionnaire in the last 90 days, the function recognises this. When used in a routing point, this function could be used to screen out repeated respondents

AnswerTimestamp(question)

Returns the exact timestamp when the answer was saved. For a question with multiple subjects, it looks at the first answered subject. Example:

AnswerTimestamp('MR')
StoreUnconnectedAnswer(question)

Stores an answer in another project, into a participation with the given unique identifier, even when the current participation and the target participation do not share the same unique identifier. Example:

StoreUnconnectedAnswer('Prj001', 'Postalcode', '123456', '1111AA', 0)
GetUnconnectedAnswer(projectid, varname, ui, default=None)

Fetches an answer from another project, from a participation with the given unique identifier, even when the current participation and the target participation do not share the same unique identifier. Example:

GetUnconnectedAnswer('Prj001', 'Postalcode', '123456')
SetRandorderFromFile(varlabel, filename, guid, ordertype='S')

Assumes that a file named ‘filename.xlsx’ is uploaded into the project’s private folder and that reach row contains a guid combined with a randomization order. This is useful when randomizations are pre-determined. Example:

SetRandorder('Myquestion', 'Myfile', UniqueIdentifier)
CountAnyRepeated()

Counts the number of answers that have a certain value within a repeater. Example:

CountAnyRepeated('MR', 1) // => this assumes that MR is in a repeater

Set functions

Sets are basically ; delimited string entities representing a group of things, for instance red;green;blue. These lists can be manipulated, ordered, reversed, randomized etcetera.

Below is a list of setfunctions. The examples are wrapped into one example at the end of the chapter. A set is basically a delimited string representing of a group of things. Eg

AddToSet(set, value[, position])

Adds items to an existing set.

see: Example of set-functions

CreateSet(setcontent)

Creates a set.

see: Example of set-functions

DeleteFromSet(set, item)

Deletes an item from the set.

see: Example of set-functions

ExtractSets(set1, set2)

Deletes all items within set2 from set1

see: Example of set-functions

InSet(set, item)

Checks for an item in a set.

see: Example of set-functions

IntersectSets(set1, set2)

Returns the intersection of two sets

see: Example of set-functions

RandomizeSet(set)

Randomizes a set.

see: Example of set-functions

ReverseSet()

Reverses the order of a set.

see: Example of set-functions

SetItem(set, position)

Returns a specific item from the set

see: Example of set-functions

SetLen(set)

Returns the length of the set

see: Example of set-functions

SetPos(str, item)

Returns the position of an item in a set

see: Example of set-functions

SortSetString(set[, unique])

Alphabetically sorts a set. When unique is true, it will return each value once even if more items in the set are the same. Note: when you sort 1;2;10; the value 10 will be right after value 1 in alphabetical order. If you want to sort by value instead, use SortSetValues

see: Example of set-functions

SortSetValues(set[, unique])

Sorts a set by ordering the values.

see: Example of set-functions

TruncateSet()

Truncates a set to the indicated length

see: Example of set-functions

Example of set-functions:

X = CreateSet(';1;2;3;4;5;6;7;') && similar to X = ';1;2;3;4;5;6;7;'
X = TruncateSet(X, 6) && X now equals ';1;2;3;4;5;6;'
X = AddToSet(X, '11' ) && X is now ';1;2;3;4;5;6;11;'
X = AddToSet(X, '7', 3) && X is now ';1;2;7;3;4;5;6;11;7;'
X = DeleteFromSet(X, '3') && X is now ';1;2;7;4;5;6;11;7;'
X = ReverseSet(X) && X is now ';7;11;6;5;4;7;2;1;'
X = ExtractSets(X, ';2;1;') && X is now ';7;11;6;5;4;7;'
V = IntersectSets(X, ';1;2;3;4;5;6;') && V is now ;4;5;6;7;
Y = SetItem(X, 3) && returns the 3rd item, so '6'
Y = SetItem(X, 100) && on out-of-range, this returns and empty element, so ''
Y = SetPos(X, '7') && returns the position of '7', so position 3
X = RandomizeSet(X) && (any random order of contained values)