x

主要章节

  1. LimeSurvey Cloud 与 LimeSurvey CE 对比
  2. 快速入门指南 - LimeSurvey 3.0+
  3. 软件安装
  4. 如何设计一个不错的调查(向导)
  5. 入门指南
  6. 管理 LimeSurvey
  7. 调查 - 说明
  8. 调查设置
  9. 问卷调查菜单
  10. 调查问卷结构
  11. 问题 - 简介
  12. 题组 - 简介
  13. 调查 - 管理
  14. 调查工具栏选项
  15. 多语言调查
  16. ExpressionScript 引擎 - 快速入门指南
  17. 其他和高级功能
  18. 常规问答
  19. 故障排除
  20. 变通方法
  21. 许可证
  22. 版本更改日志
  23. 插件
 Actions

ExpressionScript 示例

From LimeSurvey Manual

本页面可能为机器翻译,可能包含错误。 查看英文原文 · 改进此翻译
This page is a translated version of the page ExpressionScript examples and the translation is 100% complete.
欢迎协助完善本文,添加您自己的示例。这将帮助其他人快速上手使用表达式脚本。


结构

本文第一部分介绍表达式的用途,以及在哪里查找/添加表达式。第二部分提供表达式的使用示例。


表达式的类别

LimeSurvey 将表达式用于以下用途:


关联

用途:隐藏题组/问题

关联用于控制题组或问题是显示还是隐藏。如果表达式的结果为“true”(即 1),则该元素将显示;否则(即表达式的结果为“false”,也就是 0),该元素将被隐藏。

类型 显示/隐藏 在哪里找 屏幕截图
问题组相关性 问题组 创建/编辑问题组 - > “相关方程:”
问题相关性 问题 创建/编辑问题 - >“相关方程:”
子问题相关性 子问题 编辑子问题 - >“相关方程:”


验证

用途:验证对问题/子问题/答案的输入或操作

验证用于控制受访者在问题中的输入或操作是否有效。如果表达式的结果为“true”(即 1),则“good”类将应用于该元素和验证消息;否则,如果表达式的结果为“false”(即 0),则“error”类将应用于该元素和验证消息。您可以在 template.css 中为这些类定义样式。

类型 验证对象 查找位置 截图
问题验证 问题 创建/编辑问题 -> “逻辑选项卡” -> “问题验证等式”
子问题验证 子问题 创建/编辑问题 -> “逻辑选项卡” -> “子问题验证公式” ‎

文本输出

用途:(执行某些操作并)输出一些文本

表达式可用于输出文本。例如,您可以进行测试或计算,并根据测试或计算的结果指定输出内容。它还可以用于插入在该表达式之前使用的问题的问题文本、答案、问题类型等。文本输出可用于任何显示文本的位置,并可返回各种结果。

使用场景 描述
微调定制 调整文本,例如,根据之前提出的性别问题,输出“先生”或“女士”
计算 计算一个值并输出,例如“您的家庭收入为 xxx”
引用 插入某个元素中的文本,例如“您的姓名是 xxx。您多大了?”


答案存储

用途:(执行某些操作,)(输出一些文本)并将内容存储到数据库中

方程式问题类型可用于将内容存储到数据库中。您可以通过表达式执行某些操作,显示方程式问题(类似于文本显示),并将表达式的结果存储到数据库中。答案将存储在响应表中。之后,该结果可用于统计功能,也可以导入到 LimeSurvey 导出功能提供的某种格式中。

表达式示例

插入上一个问题的答案

用途 插入上一个问题的答案
类型 引用
示例 问题一(问题代码“Q00”):您居住在哪个城市?
问题二(问题代码“Q01”):您在 CITY 居住了多久?
目标:使用问题一的答案替换第二个问题中的“CITY”。
表达式 {QOO}
描述 Q00 中提供的答案将替换第二个问题中的 Q00 字段
步骤 创建/编辑问题二
在问题文本字段中输入“您在 {QOO} 居住了多少年?”

使用隐藏的方程式问题自动填写答案

问题: 假设您有两个问题 Q1 和 Q2。Q1 询问受访者的年龄。Q2 将受访者分为三组:年龄小于 20 岁、年龄等于 20 岁、年龄大于 20 岁。 因此,Q2 应使用与上述条件对应的值“1”、“2”、“3”。此外,别忘了将 Q2 设为不可见(该问题不会在调查中显示,但这些值会通过“后台进程”保存到响应表中)。

使用方程式问题类型填充数据库:

  • 首先,创建一个问题代码为 Q1 的数字输入问题。
  • 然后创建另一个问题代码为 Q2 的方程式问题。
  • 在 Q2 的“显示设置”选项卡中:
    • 将“始终隐藏本题”字段设置为“开”
    • 在“方程式”字段中输入以下表达式:
{if(Q1.NAOK < 20, "1", if(Q1.NAOK > 20, "3", "2"))}

使用占位符创建摘要页面

本教程演示如何通过 ExpressionScript 占位符 在调查结束时创建概览,列出所有问题和答案。 同时还演示了如何将此类概览限制为仅显示已回答的问题。

您可以从这里下载我们的示例:调查占位符示例调查。


此处使用的问题类型:

1. 单选题 / 单文本/数字问题

  • 列表(下拉)
  • 列表(单选) [L]
  • 是/否 [Y]
  • 长自由文本 [T]
  • 短自由文本 [S]
  • 数字输入 [N]
  • 方程式 [*]


2. 带子问题的问题

  • 多短文本 [Q]
  • 多选题 [M]
  • 阵列 [F]
  • 阵列 (是/否/不确定) [C]
  • 阵列(10分制选择题) [B]


3. 带两个尺度的问题

  • 阵列双尺度 [1]


4. 带 X 和 Y 尺度的问题

  • 阵列(数字) [:]


5. 掩码问题

  • 文本显示 [X]


在这个简单的示例中,我们的概览将是一个简单的列表,格式如下:

- 问题文本:用户的答案


单选题 / 单文本/数字问题

对于以下所有问题类型,LimeSurvey 只会存储一个反馈:

  • 列表(下拉)
  • 列表(单选)
  • 带评论的列表
  • 5分制选择题
  • 是/否
  • 短自由文本
  • 长自由文本
  • 巨大自由文本
  • 数字输入
  • 方程式
  • 日期
  • 性别

假设该问题的问题代码为 q1,我们可以使用以下方式引用问题文本和答案:

- {q1.question}: {q1.shown}

示例:

- 您多大年龄?: 25


如果您想检查该问题是否已被回答,可以在输出外围添加 IF 语句:

{if(!is_empty(q1),join("- ",q1.question,": ",q1.shown),"")}

这段表达式的“含义”是:如果问题代码为 q1 的问题不为空,则输出“- ”以及问题文本、“: ”和答案文本(join() 函数将多个元素连接为一个新字符串);否则不输出任何内容("" 表示空字符串)。

带子问题的问题

LimeSurvey 对以下所有问题类型使用子问题:

  • 多短文本
  • 多选题
  • 带评论的多选题
  • 阵列
  • 阵列(5分制选择题)
  • 阵列(10分制选择题)
  • 阵列 (是/否/不确定)
  • 阵列 (增加,不变,减少)
  • 按列阵列

假设该问题的问题代码为 q2,子问题编号为 SQ001、SQ002 等(由 LimeSurvey 自动编号),我们可以使用以下方式引用问题文本和答案:

- {q2_SQ001.question}: {q2_SQ001.shown}

- {q2_SQ002.question}: {q2_SQ002.shown}

对于多选题,更合理的做法是不显示被勾选子问题的文本,而是为每个已选选项显示 Y:

- {q2_SQ001.question}: {q2_SQ001}

- {q2_SQ002.question}: {q2_SQ002}

...

请注意,目前无法输出带子问题的问题的问题文本,请参阅此功能请求。


示例 1(假设问题类型为多选题)

- 您知道这些汽车品牌吗?

-- Mercedes: Y

-- Audi: N

-- Volvo: Y


如果您只想输出已勾选的项目,可以在输出内容外加一个 IF 语句,并检查复选框的值:

{ if( q2_SQ001=="Y", join( "- ", q2_SQ001.question, ": ", q2_SQ001.shown ), "" ) }


如果您只想输出所选项目的列表,请使用 listifop 函数,例如:Mercedes, Volvo

{ listifop( 'value', '==', 'Y', 'question', ', ', that.q2.sgqa ) }


其中  that.q2  会展开为 q2 的所有子问题。更多详情请参见 self、this 和 that。


示例 2(假设问题类型为阵列(10分制选择题))

- 请对下列汽车品牌的质量进行评分,1=非常差,10=非常好?

-- Mercedes: 7

-- Audi: 9

-- Volvo: 9


如果您只想输出已评分的项目,可以在输出内容外加一个 IF 语句,并通过以下方式检查当前子问题是否已作答:

{ if( ! is_empty( q3_SQ001 ), join( "- ", q3_SQ001.question, ": ", q3_SQ001.shown ), "" ) }


例如,如果您只想输出所选项目中大于八的项目列表,请使用 listifop 函数,例如:Audi / Volvo

{ listifop( 'value', '>', 8, 'question', ' / ', that.q3.sgqa ) }


带有两个尺度的问题

这仅适用于双尺度问题类型。


假设使用了以下代码:

  • 问题编码:q4
  • 子问题代码:SQ001, SQ002, ...
  • 尺度1的回复编号:A1, A2, ...
  • 尺度2的回复编号:B1, B2, ...


要引用某个尺度上某个子问题的结果,您需要使用 QuestionCode . '_' . SubQuestionCode . '_' . ScaleID。请注意,第一个尺度的 "ScaleID" 为 0,另一个为 1!
引用第三个子问题、第二个尺度的答案示例:q4_SQ003_1 - 问题 4,子问题 3,第二个尺度。


让我们输出两个尺度以及前两个子问题的结果:

- {q4_SQ001_0.question}: {q4_SQ001_0.shown} / {q4_SQ001_1.shown}

- {q4_SQ002_0.question}: {q4_SQ002_0.shown} / {q4_SQ002_1.shown}

要输出子问题文本,您需要在占位符中添加尺度 ID(尽管两个尺度的文本相同)。因此,我们必须使用 {q4_SQ001_0.question} 或 {q4_SQ001_1.question},而不是 {q4_SQ001.question}。

如果您只想导出/显示至少有一个答案的子问题的结果,请对每个子问题使用以下语法:

{if(count(q4_SQ001_0,q4_SQ001_1)>0,join("- ",q4_SQ001_0.question,": ",q4_SQ001_0.shown," / ",q4_SQ001_1.shown),"")}

带有 X 和 Y 尺度的问题

这适用于所有允许对每个单元格作答的矩阵问题(而不是像前面所示那样仅对每一行作答):

  • 阵列文本
  • 阵列数字


假设使用以下代码:

  • 问题代码:q5
  • 子问题代码:SQ001、SQ002、...
  • 答案代码:A1、A2、...

要引用某个子问题在某一列中的结果,您需要使用 QuestionCode . '_' . SubQuestionCode . '_' . AnswerCode。例如,引用第三个子问题、第二列的答案:q5_SQ003_A2。

我们来输出前两个子问题第 1-3 列的结果:

- {q5_SQ001_A1.question}: {q5_SQ001_A1.shown} | {q5_SQ001_A2.shown} | {q5_SQ001_A3.shown}

- {q5_SQ002_A1.question}: {q5_SQ002_A1.shown} | {q5_SQ002_A2.shown} | {q5_SQ002_A3.shown}


由于对于这些问题类型,每个单元格(X 轴和 Y 轴的组合)都对应一个答案选项,因此需要对每个单元格检查是否存在数据。示例:

{if(!is_empty(q5_SQ001_A1),join("- ",q5_SQ001_A1.question,": ",q5_SQ001_A1.shown),"")}


要输出子问题文本,您需要在占位符中添加答案代码(尽管所有答案选项的文本都相同)。因此,我们必须使用 {q5_SQ001_A1.question} 或 {q5_SQ001_A2.question},而不是 {q5_SQ001.question}。

如果上一个问题的答案为空,则隐藏问题

目的 如果上一个问题的答案为空,则隐藏问题
类型 问题相关性
示例 问题一:问题代码 "name",问题文本 "What's your name?"
问题二:问题文本 "{name}, how old are you?"
任务:如果问题一的文本框为空,则隐藏问题二
表达式 !is_empty(name)
描述 is_empty() 用于判断变量是否为空。"!" 对结果取反。因此,如果变量不为空,表达式为真,问题将被显示
步骤 创建/编辑问题二
在 "相关表达式" 中输入 "!is_empty(name)"
示例文件 Hide_question_if_empty_question_group.zip


如果上一个问题的答案为“是”或“否”,则隐藏题组

目的 如果上一个问题的答案为“是”或“否”,则隐藏题组
类型 题组相关性
示例 第一页,题组一,问题一:问题代码 "PET",问题文本 "Do you have a pet?" -Yes -No
第二页,题组二:标题 "About your pet(s)"
任务:根据问题一的答案为“是”/“否”来显示/隐藏题组二
表达式 PET == "Y"
描述 PET 是您要检查其答案的问题的问题代码。如果不使用后缀,EM 将使用 "Qcode.code"。因此,您是将 PET 问题的答案代码与值 "Y" 进行比较。如果参与者回答“是”,则表达式为真,题组 "About your pet(s)" 将被显示。
步骤 创建/编辑题组二
在 "相关表达式" 中输入 "PET == "Y""
示例文件 Hide_question group_if_answer_from_previous_question_is_Yes_or_No.zip


显示多答案输入问题字段的值

目的 显示多答案输入问题字段的值
类型 引用
示例 问题一:问题代码 "AskChildAge",问题文本 "How old are your children?"。子问题代码 -Child1 -Child2 -Child3 - ChildXXX
问题二:问题代码 "ReportChildAge",问题文本 "About your first child: - CHILD1 is AGE1."
表达式 {AskChildAge_Child1.question}, {AskChildAge_Child1.value}
描述 您想在后续问题中使用某个子问题的值。您可以通过这种表达式访问子问题的值:QcodeQuestion_QcodeSubquestion.value
步骤 创建/编辑第二个问题
在描述中输入以下文本:"About your first child: - {AskChildAge_Child1.question} is {AskChildAge_Child1.value}."
示例文件 Display_value_of_a_multiple_answer_input_question_field.zip

验证“阵列(数字)复选框”问题中每行勾选的框数

目的 验证每行勾选的框数
类型 验证
示例 “阵列数字(复选框布局)”类型的问题
表达式 sum(...)
描述 (sum(Test_A_1, Test_A_2, Test_A_3, Test_A_4, Test_A_5) <= X) 用于判断 A 行中是否至少勾选了 X 个复选框。
如果要检查全部三行(A、B、C),可以使用 "&&" 连接表达式:
(sum(Test_A_1, Test_A_2, Test_A_3, Test_A_4, Test_A_5) <= X)
&& (sum(Test_B_1, Test_B_2, Test_B_3, Test_B_4, Test_B_5) <= X)
&& (sum(Test_C_1, Test_C_2, Test_C_3, Test_C_4, Test_C_5) <= X)
步骤 创建/编辑“阵列数字(复选框布局)”类型的问题。
在高级问题设置的“问题验证等式”中输入上述表达式(您可能需要调整变量名称!)。
示例文件 Validate number of boxes ticker per row for an Array (Numbers) Checkbox.lss

计算两个日期之间的差值

目的 计算两个日期之间的差值
类型 相关性 / 方程式问题类型 / 验证
示例 问题一(日期/时间,代码:DOB):您的出生日期是什么?
问题二(日期/时间,代码:datetoday):今天的日期是什么?
问题三(样板文本):您已出生 XXXX 天。
任务:计算并显示问题一与问题二所给日期之间相差的天数。
表达式 {(strtotime(datetoday)-strtotime(DOB))/60/60/24}
描述 strtotime 计算 1970 年 1 月 1 日与给定日期之间的秒数。上述表达式计算两个给定日期之间的秒数。"/60/60/24" 部分则将秒数换算为天数。
除了询问 "datetoday" 之外,您也可以使用 strtotime('now') 或直接使用 time(),它会直接返回从 1970 年 1 月至今(即填写调查的时间)的秒数。因此,您可以使用方程式 {(time() - strtotime(DOB)) / 60 / 60 / 24 / 365.25} 快速算出一个人的年龄(以年为单位)。在上述任何情况下,日期都必须以正确的格式输入,否则 strtotime() 函数将无法正常工作。
步骤 创建两个日期问题(分别用于出生日期和今天的日期)以及一个样板文本问题。
在样板文本问题的问题文本中输入:"On {datetoday} you were {(strtotime(today)-strtotime(dob))/60/60/24} days days old."

请注意:strtotime 函数可以处理许多日期格式,但并非所有格式。如果遇到问题,请将调查的日期格式设置为 mm/dd/yyyy、yyyy-mm-dd 或 dd.mm.yyyy"
示例文件 Date_difference.zip

使用 ExpressionScript 进行评估

下面是另一个示例,介绍如何将 ExpressionScript 与阵列类型问题和评估结合使用:</ br>

假设您有 2 个阵列问题,并希望将计算结果数据保存到数据库中。这其实很简单,您需要创建并测试您的阵列,然后提交一份测试反馈,以查看其是否正常工作,并在完成页面中给出结果。


实施细节:

  • 添加一个方程式类型的问题
  • 添加以下一行,假设 Q1 是您的阵列问题代码,而 Q2 是第二个阵列问题代码:
    • {sum(Q1_SQ001.value,Q2_SQ001.value)}

请注意,SQ001 是任何子问题的默认代码。如果您更改了子问题代码,请相应地调整上面的方程式。


在阵列中使用 em_validation_q

您可以使用问题验证等式,通过任意条件来控制阵列。


实施细节:

  • 对于第一个阵列:单项选择阵列
    • 问题代码为 ARRAY
    • 子问题代码为 SQ01、SQ02、SQ03 和 SQ04
    • 更新整个问题验证等式,并输入
      !is_empty(ARRAY_SQ01) and !is_empty(ARRAY_SQ03) 
  • 对于第二个阵列:文本阵列
    • 问题代码为 ARRAYTEXT
    • Y 轴上的子问题代码为 SY01、SY02、SY03 和 SY04
    • 更新整个问题验证等式,并输入
      count(self.sq_SY01 >= 1) and count(self.sq_SY03 >= 3)