Expression Manager
From LimeSurvey Manual
บทเรียนเริ่มต้นอย่างรวดเร็ว
ภาพรวม
เมื่อปรับแต่งแบบสำรวจของคุณ โดยทั่วไปคุณจะต้องมีวิธีกำหนดสิ่งต่อไปนี้:
- การนำทาง/การแตกกิ่ง (Navigation/Branching) - ให้คำตอบของผู้ตอบเปลี่ยนลำดับการถามคำถามได้
- การปรับแต่ง/การแทรกค่า (Tailoring/Piping) - วิธีเรียบเรียงคำถาม (เช่น การอ้างอิงคำตอบก่อนหน้า หรือการผันประโยคตามจำนวนหรือเพศของผู้ตอบ) หรือวิธีสร้างรายงานแบบกำหนดเอง (เช่น คะแนนการประเมินหรือคำแนะนำที่ปรับให้เหมาะกับแต่ละบุคคล)
- การตรวจสอบ (Validation) - ตรวจสอบให้แน่ใจว่าคำตอบผ่านเกณฑ์ที่กำหนด เช่น ค่าต่ำสุดและค่าสูงสุด หรือตรงกับรูปแบบที่ป้อน
Expression Manager (EM) มอบวิธีที่เข้าใจง่ายในการกำหนดตรรกะสำหรับแต่ละฟีเจอร์เหล่านั้น เกือบทุกสิ่งที่คุณเขียนเป็นสมการทางคณิตศาสตร์มาตรฐานได้ถือเป็นนิพจน์ที่ถูกต้อง แม้จะมีการเรียกใช้ฟังก์ชันก็ตาม ปัจจุบัน EM มีฟังก์ชันให้ใช้งาน 80 ฟังก์ชัน และสามารถขยายเพิ่มเติมได้อย่างง่ายดาย นอกจากนี้ยังช่วยให้คุณเข้าถึงตัวแปรโดยใช้ชื่อตัวแปรที่มนุษย์อ่านเข้าใจได้ (แทนที่จะเป็นชื่อแบบ SGQA)
ส่วนต่อไปนี้แสดงจุดหลักที่มีการใช้งาน Expression Manager
ความสัมพันธ์กัน (การควบคุมการนำทาง/การแตกกิ่ง)
แบบสำรวจบางชุดใช้ "ตรรกะ Goto" เช่น หากคุณตอบคำถามที่ 1 ด้วยตัวเลือก C ให้ข้ามไปยังคำถามที่ 5 แนวทางนี้มีข้อจำกัดมาก เนื่องจากตรวจสอบได้ยาก และเสียหายง่ายเมื่อต้องเรียงลำดับคำถามใหม่ EM ใช้สมการความสัมพันธ์กันแบบบูลีนเพื่อระบุเงื่อนไขทั้งหมดที่คำถามอาจใช้ได้ หากคำถามมีความสัมพันธ์กัน คำถามจะถูกแสดง มิฉะนั้นจะเป็น Not Applicable และค่า NULL จะถูกจัดเก็บในฐานข้อมูล ซึ่งคล้ายกับสิ่งที่ทำได้ผ่านตัวแก้ไขเงื่อนไข (Conditions editor) แต่ EM ช่วยให้คุณกำหนดเกณฑ์ที่ซับซ้อนและทรงพลังกว่ามากได้อย่างง่ายดาย (และให้คุณใช้ชื่อตัวแปรแทนการตั้งชื่อแบบ SGQA)
ภาพนี้แสดงวิธีหนึ่งในการตรวจสอบตรรกะความสัมพันธ์กันของแบบสำรวจ โดยคำนวณดัชนีมวลกาย สมการความสัมพันธ์กันจะแสดงในวงเล็บเหลี่ยมถัดจากชื่อตัวแปร (ซึ่งเป็นสีเขียว) ดังนั้น ความสัมพันธ์กันของ weight, weight_units, height และ height_units จึงเป็น 1 ทั้งหมด หมายความว่าคำถามเหล่านั้นจะถูกถามเสมอ อย่างไรก็ตาม ความสัมพันธ์กันของ BMI คือ {!is_empty(height) and !is_empty(weight)} ซึ่งหมายความว่า BMI จะถูกคำนวณก็ต่อเมื่อผู้ตอบป้อนค่าทั้งส่วนสูงและน้ำหนัก (จึงหลีกเลี่ยงความเสี่ยงของข้อผิดพลาดการหารด้วยศูนย์) นอกจากนี้ คำถาม Report จะแสดงก็ต่อเมื่อผู้ตอบตอบคำถามหลักทั้งสี่ข้อ (height, height_units, weight, weight_units)
ความสัมพันธ์กันจะแสดงและแก้ไขได้ในตำแหน่งต่อไปนี้:
การดู / การแก้ไขความสัมพันธ์กันระดับคำถาม
สมการนี้คำนวณดัชนีมวลกาย (BMI) และจะถูกถามก็ต่อเมื่อผู้ตอบป้อนส่วนสูงและน้ำหนักก่อน
นี่คือหน้าจอแก้ไขสำหรับคำถาม BMI
โปรดทราบว่าคุณไม่ต้องใช้วงเล็บปีกกาเมื่อป้อนสมการความสัมพันธ์กัน
การดู / การแก้ไขความสัมพันธ์กันระดับกลุ่ม
นี่คือตัวอย่างแบบสำรวจสำมะโนประชากร หน้าแรกถามว่ามีกี่คนที่อาศัยอยู่กับคุณและเก็บค่านั้นไว้ในตัวแปร "cohabs" หน้านี้จะแสดงก็ต่อเมื่อคุณมีผู้อยู่อาศัยร่วมมากกว่าหนึ่งคน (จึงแสดงสำหรับบุคคลที่สองที่อยู่อาศัยร่วมกับคุณ) และจะแสดงก็ต่อเมื่อคุณระบุแล้วว่าบุคคลที่หนึ่งเกี่ยวข้องกับคุณอย่างไร (p1_rel)
อย่างที่เห็น กลุ่มนี้มีเกณฑ์ความสัมพันธ์กันระดับคำถามด้วย โดยแต่ละคำถามจะปรากฏเมื่อคุณตอบคำถามก่อนหน้าแล้วเท่านั้น (เช่น {!is_empty(p1_sex)}) EM จะรวมความสัมพันธ์กันระดับกลุ่มและระดับคำถามให้คุณโดยอัตโนมัติ คำถามในกลุ่มจะถูกถามก็ต่อเมื่อกลุ่มโดยรวมมีความสัมพันธ์กัน จากนั้นจึงถามเฉพาะชุดย่อยของคำถามในกลุ่มที่มีความสัมพันธ์กันเท่านั้น
นี่คือหน้าจอสำหรับแก้ไขความสัมพันธ์กันระดับกลุ่มของคำถามนั้น:
โปรดทราบว่าคุณไม่ต้องใช้วงเล็บปีกกาเมื่อป้อนสมการความสัมพันธ์กัน
การปรับแต่ง/การแทรกค่า (Tailoring/Piping)
EM ช่วยให้คุณปรับแต่งคำถามแบบมีเงื่อนไขได้ทั้งแบบง่ายและซับซ้อน บางครั้งคุณต้องการเพียงการแทนที่ค่าอย่างง่าย เช่น "คุณบอกว่าคุณซื้อ [ผลิตภัณฑ์] คุณชอบอะไรเกี่ยวกับผลิตภัณฑ์นั้นมากที่สุด" บางครั้งคุณต้องการการแทนที่แบบมีเงื่อนไข เช่น "[นาย/นาง] [นามสกุล] คุณยินดีตอบแบบสำรวจของเราหรือไม่" ในกรณีนี้ คุณต้องการใช้คำนำหน้า นาย หรือ นาง ตามเพศของบุคคล บางครั้งคุณต้องการการแทนที่ที่ซับซ้อนยิ่งขึ้น (เช่น ตามผลการคำนวณทางคณิตศาสตร์) EM รองรับการปรับแต่ง/การแทรกค่าทุกประเภทเหล่านี้
สมการแบบมีเงื่อนไข
ตัวอย่างดัชนีมวลกายแสดงความสามารถในการคำนวณ BMI ของบุคคล แม้จะให้ผู้ตอบป้อนส่วนสูงและน้ำหนักในหน่วยเมตริกหรือไม่ใช่เมตริกก็ตาม
ในที่นี้ weight_kg คือ {if(weight_units == 'kg', weight, weight * .453592)} ฟังก์ชัน if() นี้หมายความว่า หากผู้ตอบกรอกน้ำหนักเป็นกิโลกรัม ให้ใช้ค่านั้น มิฉะนั้นให้นำค่าที่กรอก (ซึ่งเป็นปอนด์) คูณด้วย .453592 เพื่อแปลงเป็นกิโลกรัม ตัวแปร height_m ใช้วิธีการคล้ายกันเพื่อคำนวณส่วนสูงเป็นเมตร แม้ว่าผู้ตอบจะกรอกส่วนสูงเป็นนิ้วก็ตาม
BMI คำนวณสูตรน้ำหนักด้วย {weight_kg / (height_m * height_m)}
สุดท้าย รายงานจะปรับข้อความสำหรับผู้ตอบตามเงื่อนไข โดยบอกสิ่งที่ผู้ตอบกรอกไว้ ("คุณบอกว่าคุณสูง 2 เมตรและมีน้ำหนัก 70 กก.")
แม้จะแสดงไว้ไม่ชัดเจนในภาพด้านบน แต่ weight_status ใช้คำสั่ง if() ซ้อนกันเพื่อจัดหมวดหมู่ผู้ตอบตั้งแต่น้ำหนักต่ำกว่าเกณฑ์ไปจนถึงอ้วนรุนแรง คุณสามารถดูสมการของมันได้ใน Show Logic View
จากหน้าต่างแก้ไขของคำถามนี้ คุณจะเห็นสองสิ่ง:
- การปรับแต่งข้อความ (Tailoring) ต้องใส่นิพจน์ไว้ในวงเล็บปีกกา
- นิพจน์สามารถเขียนหลายบรรทัดได้ เช่นในกรณีนี้ ซึ่งช่วยให้อ่านตรรกะเงื่อนไขที่ซ้อนกันได้ง่ายขึ้น
คำถาม คำตอบ และรายงานที่ปรับแต่งตามผู้ตอบ
ตัวอย่างนี้แสดงรายงาน BMI
นี่คือหน้าต่างแก้ไขของคำถามเดียวกัน
อย่างที่เห็น ข้อความใดๆ ในวงเล็บปีกกาจะถือเป็นนิพจน์ จึงมีการไฮไลต์ไวยากรณ์ (แยกสี) ในภาพก่อนหน้า หากคุณพิมพ์ผิด (เช่น สะกดชื่อตัวแปรหรือฟังก์ชันผิด หรือใช้ตัวแปรหรือฟังก์ชันที่ไม่ได้กำหนด) EM จะแสดงข้อผิดพลาด ดังตัวอย่างนี้ ซึ่งแสดงว่า height_unit เป็นชื่อตัวแปรที่ไม่ได้กำหนด (ที่ถูกต้องคือ height_units) และ rnd() เป็นฟังก์ชันที่ไม่ได้กำหนด (ชื่อฟังก์ชันที่ถูกต้องคือ round()) ในทั้งสองกรณี ข้อผิดพลาดจะถูกล้อมด้วยกรอบสีแดงเพื่อให้มองเห็นและแก้ไขได้ง่ายขึ้น
คุณยังเห็นได้ว่าสามารถสร้างรายงานที่ซับซ้อนได้อย่างรวดเร็ว เช่น ตารางค่าที่กรอก หรือคำแนะนำที่ปรับตามผู้ตอบ
โปรดจำไว้ว่าการปรับแต่งข้อความทั้งหมดต้องใส่นิพจน์ไว้ในวงเล็บปีกกา เพื่อให้ LimeSurvey ทราบว่าส่วนใดของคำถามเป็นข้อความธรรมดา และส่วนใดต้องถูกประมวลผลผ่าน Expression Manager
การตรวจสอบ
EM ควบคุมการทำงานของตัวเลือกขั้นสูงของคำถามส่วนใหญ่ ซึ่งควบคุมเรื่องต่างๆ เช่น จำนวนคำตอบขั้นต่ำ/สูงสุด ค่าแต่ละค่าขั้นต่ำ/สูงสุด ผลรวมขั้นต่ำ/สูงสุด และการตรวจสอบว่าค่าที่กรอกตรงกับรูปแบบสตริงที่กำหนดหรือไม่ คุณยังคงกรอกตัวเลือกขั้นสูงของคำถามเหล่านั้นตามปกติ แต่ตอนนี้ค่าใดๆ ในช่องเหล่านั้นจะถือเป็นนิพจน์ ดังนั้นคุณจึงกำหนดเกณฑ์ขั้นต่ำ/สูงสุดที่มีความสัมพันธ์แบบมีเงื่อนไขซับซ้อนกับคำถามอื่นได้
ในทุกกรณีเหล่านี้ เนื่องจากตัวเลือกขั้นสูงของคำถามจะถือเป็นนิพจน์เสมอ คุณจึงไม่ต้องใช้วงเล็บปีกกาเมื่อระบุค่า
หน้า แบบสำรวจตัวอย่าง แสดงตัวอย่างการใช้งานนิพจน์เพื่อการตรวจสอบมากมาย
บทนำ
LimeSurvey ใช้โมดูล Expression Manager (EM) ใหม่ ซึ่งช่วยให้ LimeSurvey รองรับการแบ่งสาย การประเมินผล การตรวจสอบ และการปรับแต่งข้อความที่ซับซ้อนยิ่งขึ้น โมดูลนี้จะมาแทนที่วิธีที่ LimeSurvey จัดการ Replacements, Conditions และ Assessments ในส่วนหลังบ้าน และยังช่วยเพิ่มความเร็วในการประมวลผลอย่างมาก เนื่องจากตัดการอ่านฐานข้อมูลขณะรันไทม์ส่วนใหญ่ออกไป EM พัฒนาโดย Dr. Thomas White (TMSWhite)
วิกิหน้านี้เป็นเอกสารอ้างอิงฉบับสมบูรณ์เกี่ยวกับไวยากรณ์และฟังก์ชันการทำงานของ Expression Manager
คำจำกัดความสำคัญ
- นิพจน์: สิ่งใดก็ตามที่อยู่ในวงเล็บปีกกา
- โดยต้องไม่มีช่องว่างทันทีหลังวงเล็บเปิดหรือก่อนวงเล็บปีกกาปิด
- เนื้อหาของนิพจน์จะถูกประเมินผลโดย EM ดังนั้นจึงอาจมีสูตรคณิตศาสตร์ ฟังก์ชัน และการประมวลผลสตริงและวันที่ที่ซับซ้อนได้
- การปรับแต่งข้อความ (Tailoring): บางครั้งเรียกว่า "piping" คือกระบวนการแก้ไขข้อความตามเงื่อนไข
- คุณเข้าถึง 'replacement fields' ข้อมูลผู้เข้าร่วม และข้อมูลการตอบคำถามทั้งหมดได้
- คุณยังเข้าถึงคำถาม คำตอบ และคุณสมบัติของสิ่งเหล่านั้นได้ง่ายขึ้นด้วย
- สมการความสัมพันธ์กัน: คุณสมบัติคำถามใหม่ที่ควบคุมการมองเห็นของคำถาม
- หากมีสมการความสัมพันธ์กัน คำถามจะแสดงก็ต่อเมื่อผลการประเมินความสัมพันธ์กันเป็นจริง
- ภายในระบบ คำสั่ง array_filter และ array_filter_exclude ทั้งหมดจะกลายเป็นความสัมพันธ์กันระดับคำถามย่อย
- สมการ ชนิดของคำถาม: ชนิดคำถามใหม่ที่บันทึกการคำนวณหรือรายงานลงฐานข้อมูล
- คล้ายกับคำถาม Boilerplate แต่เนื้อหาจะถูกบันทึกลงฐานข้อมูลแม้คุณจะตั้งค่า "ซ่อนคำถามนี้"
- รหัสคำถาม: นี่คือชื่อตัวแปรที่แนะนำสำหรับ EM
- อาจเป็นชื่อเชิงอธิบายที่บอกวัตถุประสงค์ของคำถาม ทำให้อ่านตรรกะที่ซับซ้อนได้ง่ายขึ้น
- รหัสคำถามที่ถูกต้องไม่ควรขึ้นต้นด้วยตัวเลข ดังนั้นเมื่อใช้รหัสคำถามเพื่อกำหนดหมายเลขคำถาม ให้ใช้เช่น "q1" หรือ "q1a" หรือ "g1q2"
- นี่คือสิ่งที่กลายเป็นชื่อตัวแปรในปัจจุบันเมื่อคุณส่งออกข้อมูลไปยัง SPSS หรือ R ดังนั้นหากคุณวิเคราะห์ทางสถิติ คุณอาจตั้งให้ไม่ซ้ำกันไว้แล้ว
ฉันต้องใช้ EM หรือไม่?
คำตอบสั้นๆ คือไม่ (แต่ก็ใช่ด้วย)
EM รองรับแบบสำรวจเดิมที่มีอยู่อย่างสมบูรณ์ ดังนั้นหากคุณพอใจที่จะใช้ Conditions และ Assessments ในรูปแบบที่ LimeSurvey ใช้ในเวอร์ชัน <= 1.91+ คุณก็ยังใช้ต่อไปได้
อย่างไรก็ตาม EM เข้ามาแทนที่วิธีที่ LimeSurvey จัดการ Conditions ภายในระบบทั้งหมด แม้ว่าคุณจะยังใช้ตัวแก้ไข Conditions เพื่อสร้างและจัดการเงื่อนไขได้ แต่ LimeSurvey 1.92 จะแปลงเงื่อนไขเหล่านั้นเป็นสมการความสัมพันธ์กันที่เทียบเท่ากัน ในระหว่างการอัปเกรด LimeSurvey 1.92 จะแปลง Conditions ที่มีอยู่ทั้งหมดเป็นสมการความสัมพันธ์กันโดยอัตโนมัติ
วิธีนี้ช่วยให้คุณได้ประโยชน์ทั้งสองด้าน คือคุณยังใช้ LimeSurvey ได้ตามที่คุ้นเคย แต่จะเห็นสมการความสัมพันธ์กันที่เทียบเท่ากัน เพื่อให้คุณค่อยๆ ย้ายไปใช้สมการความสัมพันธ์กันโดยตรงได้ตามที่เห็นสมควร
ฉันสามารถใช้เงื่อนไข (Conditions) ร่วมกับความสัมพันธ์กัน (Relevance) ได้หรือไม่
ได้ คุณสามารถใช้ตัวแก้ไขเงื่อนไข (Conditions editor) กับบางคำถาม และใช้ตัวแก้ไขความสัมพันธ์กัน (Relevance editor) กับคำถามอื่นได้ เงื่อนไขจะถูกแปลงเป็นความสัมพันธ์กันโดยอัตโนมัติเมื่อคุณบันทึกคำถาม
โปรดทราบว่าเราสันนิษฐานว่าหากคุณใช้ตัวแก้ไขเงื่อนไข คุณต้องการให้เงื่อนไขเหล่านั้นเขียนทับสมการความสัมพันธ์กันที่ป้อนด้วยตนเอง ดังนั้น หากคุณมีเงื่อนไขอยู่แล้วและต้องการแก้ไขความสัมพันธ์กันด้วยตนเอง โปรดลบเงื่อนไขของคำถามนั้นก่อน กล่าวคือ ให้คัดลอกสมการความสัมพันธ์กันที่ถูกสร้างขึ้นไปยังโปรแกรมแก้ไขข้อความ ใช้เมนูเงื่อนไขเพื่อลบเงื่อนไขทั้งหมดของคำถามนั้น (ซึ่งจะลบความสัมพันธ์กันด้วย) จากนั้นแก้ไขคำถามและวางสมการความสัมพันธ์กันที่สร้างขึ้นจากโปรแกรมแก้ไขข้อความกลับลงในช่องความสัมพันธ์กันของคำถามนั้น (แล้วบันทึกคำถาม) หากมีความต้องการเพียงพอในการลบเงื่อนไขโดยไม่ลบสมการความสัมพันธ์กันที่สร้างขึ้น เราอาจเพิ่มกระบวนการแปลงเป็นกลุ่มได้
ฉันควรเลือกระหว่างเงื่อนไข (Conditions) และความสัมพันธ์กัน (Relevance) อย่างไร
นี่คือรายการข้อดีและข้อเสียของแต่ละรูปแบบ:
| รูปแบบ | ข้อดี | ข้อเสีย |
|---|---|---|
| เงื่อนไข (Conditions) | 1. มี GUI ที่ใช้งานง่ายสำหรับสร้างเงื่อนไขอย่างง่าย 2. GUI มีเอกสารประกอบที่ดีและทีมสนับสนุนเข้าใจดี |
1. รองรับเฉพาะการเปรียบเทียบอย่างง่าย และจัดการเงื่อนไข AND/OR ได้ไม่ดี 2. เงื่อนไขแบบเรียงต่อกันทำงานไม่แน่นอน 3. ช้า - ใช้ฐานข้อมูลมาก จึงอาจทำให้แบบสำรวจที่ยาวช้าลง 4. มีรายงานปัญหาบางอย่างเกี่ยวกับการโหลดเงื่อนไขซ้ำ 5. GUI ไม่รองรับการขยายขนาดได้ดีเมื่อมีคำถามหลายสิบ หลายร้อย หรือหลายพันข้อ 6. อาจแปลงแบบสำรวจที่เป็นกระดาษได้ช้า เพราะต้องใช้ชื่อ SGQA 7. มักต้องใช้โปรแกรมเมอร์เขียนโค้ดตรรกะที่จำเป็นสำหรับการแตกกิ่งที่ซับซ้อน |
| ความสัมพันธ์กัน (Relevance) | 1. รองรับตรรกะที่ซับซ้อนมาก รวมถึงฟังก์ชันมากกว่า 80 ฟังก์ชัน และตัวดำเนินการทางคณิตศาสตร์/สตริง 2. รองรับตรรกะแบบเรียงต่อกันได้อย่างสมบูรณ์ 3. เร็ว - ไม่มีการเรียกฐานข้อมูลเพิ่มเติม จึงรองรับแบบสำรวจที่มีคำถามมากกว่า 1000 ข้อ 4. ไม่มีปัญหาในการโหลดตรรกะซ้ำ เพราะไม่ต้องใช้รหัส SGQA 5. การเน้นไวยากรณ์ (syntax-highlighting) รองรับแบบสำรวจที่มีคำถามมากกว่า 1000 ข้อ 6. ใช้งานง่ายและรวดเร็วสำหรับกลุ่มที่ต้องการทำแบบสำรวจกระดาษที่มีอยู่ให้เป็นระบบคอมพิวเตอร์ 7. รองรับการสัมภาษณ์กึ่งโครงสร้างและแบบสำรวจทางระบาดวิทยาได้ง่ายโดยไม่ต้องใช้โปรแกรมเมอร์ |
1. ไม่มี GUI สำหรับเงื่อนไขอย่างง่าย - ให้ใช้การเน้นไวยากรณ์แทน 2. เป็นของใหม่ ทีมสนับสนุนจึงยังไม่เชี่ยวชาญ EM |
สรุปคือ หากคุณพอใจกับการทำงานของ LimeSurvey 1.91+ ก็ไม่มีเหตุผลที่ต้องเปลี่ยนวิธีที่คุณทำอยู่
ประโยชน์อื่น ๆ ของการใช้ EM มีอะไรบ้าง
นี่คือเหตุผลอื่น ๆ ที่คุณอาจต้องการใช้ EM
- การคำนวณ - คุณสามารถสร้างการคำนวณใดก็ได้ตามที่คิด:
- คุณสามารถใช้ตัวดำเนินการและฟังก์ชันทางคณิตศาสตร์ทั่วไปได้ทั้งหมด
- คุณสามารถใช้ฟังก์ชันทางคณิตศาสตร์ วันที่ และการประมวลผลสตริงมากกว่า 70 ฟังก์ชัน
- นักพัฒนาสามารถเพิ่มฟังก์ชันใหม่ได้ค่อนข้างง่ายหากผู้ใช้ต้องการ
- การจัดเก็บการคำนวณลงฐานข้อมูล
- ตอนนี้คุณสามารถคำนวณอย่างง่ายและซับซ้อน และ/หรือคะแนนตามมาตราส่วน และจัดเก็บลงฐานข้อมูลได้โดยไม่ต้องใช้ JavaScript
- คุณใช้คำถามประเภทสมการ (Equation) เพื่อทำเช่นนี้
- การประเมิน
- ตอนนี้คุณสามารถสร้างการประเมินหรือคะแนนตามมาตราส่วนจากคำถามประเภทใดก็ได้ ไม่จำกัดเฉพาะบางประเภทเหมือนก่อนหน้านี้
- คุณสามารถใช้การปรับแต่งข้อความ (Tailoring) เพื่อแสดงคะแนนการประเมินแบบสะสมหรือคะแนนรวมได้ทุกที่ที่ต้องการ แม้อยู่ในหน้าเดียวกัน
- คุณควบคุมรายงานที่สร้างขึ้นจากคะแนนการประเมินเหล่านั้นได้มากขึ้น
- คุณสามารถจัดเก็บคะแนนการประเมินลงฐานข้อมูลได้โดยไม่ต้องใช้ JavaScript
- คุณสามารถซ่อนคะแนนการประเมินได้โดยไม่ต้องใช้ JavaScript หรือ CSS
- ฟิลด์แทนที่ (Replacement Fields)
- ใช้รหัสคำถามเพื่อแทรกค่าจากคำตอบของคำถามก่อนหน้า - ซึ่งทำให้อ่านและตรวจสอบได้ง่ายขึ้น
- การปรับแต่งข้อความ (Tailoring) - คุณสามารถแสดงข้อความตามเงื่อนไขโดยอิงจากค่าอื่น ๆ
- ใช้คำนำหน้าชื่อที่เหมาะสมกับผู้ตอบ เช่น (เช่น "สวัสดี [คุณ/นาง] สมิธ")
- แสดงประโยคที่ถูกต้องตามหลักไวยากรณ์เมื่อเอกพจน์/พหูพจน์มีความสำคัญ: (เช่น "คุณมีลูก 1 คน" เทียบกับ "คุณมีลูก 2 คน")
- เปลี่ยนรูปคำกริยาและคำนามให้เหมาะสมตามเพศและจำนวนของผู้ตอบ
- แอตทริบิวต์ของตัวแปรใหม่ - คุณสามารถเข้าถึงสิ่งต่อไปนี้เพื่อปรับแต่งข้อความ:
- (ไม่มีคำต่อท้าย) - เป็นนามแฝงของ qcode.code
- .code - รหัสคำตอบที่เลือกสำหรับคำถามหากคำถามนั้นเกี่ยวข้อง (มิฉะนั้นจะว่างเปล่า) หรือค่าข้อความหากไม่ใช่คำถามที่มีรหัส
- .NAOK - เหมือน .code แต่สามารถเป็นส่วนหนึ่งของการคำนวณหรือรายการได้ แม้ไม่เกี่ยวข้อง
- .value - ค่าการประเมินของคำถามหากคำถามนั้นเกี่ยวข้อง (มิฉะนั้นจะว่างเปล่า) หรือค่าข้อความหากไม่ใช่คำถามที่มีรหัส -- ใช้ได้เมื่อเปิดใช้การประเมินสำหรับแบบสำรวจ มิฉะนั้นจะเป็นศูนย์เสมอ
- .valueNAOK - เหมือน .value แต่สามารถเป็นส่วนหนึ่งของการคำนวณหรือรายการได้ แม้ไม่เกี่ยวข้อง
- .shown - คำตอบตามที่แสดงให้ผู้ใช้เห็น
- .qid - หมายเลขคำถาม
- .gid - หมายเลขกลุ่ม
- .sgqa - ค่า SGQA ของคำถาม
- .jsName - ชื่อตัวแปร javascript ที่ถูกต้องของคำถาม ไม่ว่าจะกำหนดไว้ในหน้านี้หรือหน้าอื่น
- .qseq - ลำดับของคำถาม (เริ่มจาก 0)
- .gseq - ลำดับของกลุ่ม (เริ่มจาก 0)
- .mandatory - คำถามนั้นจำเป็นต้องตอบหรือไม่ (Y/N)
- .question - ข้อความของคำถาม
- .relevance - สมการความสัมพันธ์กันของคำถาม
- .grelevance - สมการความสัมพันธ์กันของกลุ่ม
- .relevanceStatus - คำถามนั้นเกี่ยวข้องในขณะนี้หรือไม่ (บูลีน (อาจแตกต่างกันระหว่าง PHP และ JS))
- .type - ประเภทคำถาม (รหัสอักขระตัวเดียว)
- การเปลี่ยนแปลงแบบไดนามิกบนหน้า
- ความสัมพันธ์กัน การคำนวณ และการปรับแต่งข้อความทั้งหมดทำงานแบบไดนามิกบนหน้า - การเปลี่ยนแปลงของค่าจะอัปเดตหน้าทันที
- ดังนั้น คำถามจะปรากฏ/หายไปแบบไดนามิกตามว่าเกี่ยวข้องหรือไม่
- คำถามยังถูกปรับแต่งแบบไดนามิกตามคำตอบบนหน้า ทำให้คุณเห็นผลรวมสะสม ประโยคที่ปรับแต่ง และรายงานที่กำหนดเองได้
- หน้ารายการข้อมูลแบบใหม่
- นอกจากการใช้ระบบรายการข้อมูลปัจจุบันแล้ว คุณสามารถใช้ Survey-All-In-One ได้
- รองรับความสัมพันธ์กันและการปรับแต่งข้อความบนหน้า ทำให้เจ้าหน้าที่ป้อนข้อมูลกด tab ผ่านได้อย่างรวดเร็ว และต้องป้อนเฉพาะคำตอบที่เกี่ยวข้องเท่านั้น
- ซึ่งอาจมีความสำคัญหากผู้ป้อนข้อมูลของคุณต้องเห็นการปรับแต่งข้อความ ซึ่งเป็นแบบไดนามิกเช่นกัน
- ลดความจำเป็นในการใช้ JavaScript ที่เขียนเองเกือบทั้งหมด
- EM รองรับการคำนวณที่ซับซ้อน การให้คะแนน การปรับแต่งข้อความ และตรรกะตามเงื่อนไขได้อย่างง่ายดาย
- บางอย่างยังคงต้องใช้ JavaScript (เช่น เลย์เอาต์ที่กำหนดเอง และการซ่อนองค์ประกอบย่อยของคำถามตามเงื่อนไข) แต่ JavaScript ของคุณสามารถใช้ฟังก์ชัน EM เพื่อเข้าถึงคำถามด้วย Qcode แทน SGQA และเข้าถึงคุณสมบัติของคำถามทั้งหมดที่ระบุไว้ข้างต้นได้
คุณสมบัติใหม่ที่เป็นประโยชน์อื่น ๆ ที่ EM เปิดใช้งานมีอะไรบ้าง
ไม่ว่าคุณจะยังใช้ตัวแก้ไขเงื่อนไขต่อไปหรือเขียนสมการความสัมพันธ์กันด้วยตนเอง คุณจะได้รับประโยชน์เพิ่มเติมดังต่อไปนี้:
- คุณสามารถสร้างเกณฑ์การตรวจสอบที่ซับซ้อนยิ่งขึ้นได้
- คุณสมบัติคำถามขั้นสูงทั้งหมด (เช่น max_answers, min_num_value_n, max_num_value) สามารถใช้นิพจน์ได้ ดังนั้นเกณฑ์ขั้นต่ำ/สูงสุดของคุณจึงปรับตามคำตอบก่อนหน้าได้อย่างง่ายดาย แม้จะอยู่ในหน้าเดียวกันก็ตาม
- EM ยังจัดการการตรวจสอบที่ใช้นิพจน์ทั่วไป (regular expression) ทั้งหมดด้วย ดังนั้นคุณจึงสามารถใช้คุณสมบัติคำถามแบบ preg และแบบสมการร่วมกันได้อย่างมั่นคง
- เรียงลำดับใหม่ (หรือลบ) คำถามและกลุ่มได้อย่างง่ายดาย
- ก่อนเวอร์ชัน 1.92 คุณไม่สามารถเรียงลำดับคำถามหรือกลุ่มใหม่ได้ หาก LimeSurvey เห็นว่าการเรียงลำดับใหม่อาจทำให้เงื่อนไขที่ใช้คำถามหรือกลุ่มเหล่านั้นเสียหาย และในทำนองเดียวกัน คุณไม่สามารถลบคำถามได้หากมีคำถามอื่นพึ่งพาอยู่
- ด้วยการเน้นไวยากรณ์ของ EM คุณจึงเห็นและตรวจสอบได้ง่ายว่าคุณใช้คำถามก่อนที่จะประกาศหรือไม่ ดังนั้นตอนนี้เราจึงให้คุณเรียงลำดับใหม่หรือลบคำถามและกลุ่มได้ทุกเมื่อ EM จะอัปเดตการเน้นไวยากรณ์ทั้งหมดเพื่อแสดงข้อผิดพลาดที่อาจเกิดขึ้น
- มุมมองเรียงลำดับคำถามใหม่ได้รับการปรับปรุงเพื่อช่วยในการตรวจทานดังกล่าว ตอนนี้จะแสดงสมการความสัมพันธ์กันและการปรับแต่งข้อความ (tailoring) ของคำถาม ทำให้คุณเห็นได้ทันทีว่ามีตัวแปรใดเปลี่ยนเป็นสีชมพูหรือไม่ (หมายถึงถูกใช้ก่อนที่จะประกาศ)
- ดัชนีการนำทางของคำถาม/กลุ่มพร้อมใช้งานและถูกต้องเสมอ
- ก่อนเวอร์ชัน 1.92 ดัชนีเหล่านี้ไม่พร้อมใช้งานหากมีเงื่อนไขที่ซับซ้อน
- ด้วย EM เราสามารถรับประกันได้ว่าดัชนีเหล่านี้ถูกต้อง
- ผู้ตอบแบบสำรวจสามารถย้อนกลับไปยังคำถามก่อนหน้า เปลี่ยนคำตอบ แล้วข้ามไปข้างหน้า (หรือส่ง) ได้
- เมื่อข้ามไปข้างหน้า EM จะตรวจสอบคำถาม/กลุ่มที่อยู่ระหว่างทางทั้งหมดอีกครั้ง
- หากคำถามใดไม่เกี่ยวข้องอีกต่อไป คำถามนั้นจะถูกตั้งค่าเป็น NULL ในฐานข้อมูล เพื่อให้ข้อมูลของคุณสอดคล้องกันภายใน
- หากคำถามใดกลายเป็นเกี่ยวข้อง หรือไม่ผ่านกฎคำถามที่จำเป็นหรือกฎการตรวจสอบขึ้นมาใหม่ EM จะหยุดอยู่ที่หน้านั้นและบังคับให้ผู้ใช้ตอบคำถามเหล่านั้นก่อนข้ามไปยังปลายทางสุดท้าย
- การแปลงเงื่อนไขเป็นความสัมพันธ์กันโดยอัตโนมัติ
- เมื่อคุณอัปเกรดฐานข้อมูล แบบสำรวจที่มีอยู่ทั้งหมดที่มีเงื่อนไขจะมีการสร้างสมการความสัมพันธ์กันให้
- ทุกครั้งที่คุณนำเข้าแบบสำรวจ จะมีการสร้างสมการความสัมพันธ์กันตามความจำเป็น
- ทุกครั้งที่คุณเพิ่ม ลบ หรือแก้ไขเงื่อนไข EM จะสร้างสมการความสัมพันธ์กันที่เหมาะสม
- การเน้นไวยากรณ์ที่สะดวก
- เมื่อ EM แสดงสมการความสัมพันธ์กัน จะแสดง Qcode แม้ว่าคุณจะป้อนรหัส SGQA ก็ตาม เนื่องจากเราคาดว่าจะอ่านง่ายกว่า
- ตัวแปรทั้งหมดมีการแยกสีเพื่อแสดงว่าถูกประกาศก่อนหรือหลังคำถามปัจจุบัน (หรือก่อนหรือหลังกลุ่มปัจจุบัน) ซึ่งช่วยให้คุณตรวจพบและแก้ไขกรณีที่คุณใช้ตัวแปรในสมการความสัมพันธ์ (รวมถึง array_filter) การปรับแต่งข้อความ หรือการตรวจสอบ ก่อนที่จะประกาศตัวแปรได้อย่างรวดเร็ว
- นอกจากนี้ หากคุณวางเมาส์เหนือตัวแปรที่มีสี คุณจะเห็นข้อมูลเมตาที่สำคัญที่สุดของคำถามนั้น ซึ่งรวมถึงลำดับกลุ่ม ลำดับคำถาม Qcode ข้อความของคำถาม และตัวเลือกคำตอบทั้งหมดที่มี (หากเป็นประเภทคำถามที่มีตัวเลือกคำตอบแบบระบุรายการ)
- รายการตัวเลือกคำตอบใช้ไวยากรณ์นี้: 'answers':{key:val, ... }
- key มีไวยากรณ์ 'scale~code' โดย scale คือมาตราส่วนของคำตอบ (เช่น สำหรับคำถามสองมาตราส่วน) และ code คือรหัสคำตอบ
- val มีไวยากรณ์ 'value~shown' โดย value คือค่าการประเมิน (หากใช้การประเมิน มิฉะนั้นคือ code) (เช่น Qcode.value) และ shown คือค่าที่แสดงให้ผู้ตอบเห็น (เช่น Qcode.shown)
- ซึ่งหมายความว่าแบบสำรวจจำนวนมากสามารถใช้การคำนวณได้โดยไม่ต้องใช้โหมดการประเมิน หากคุณมีตัวเลือกคำตอบแบบระบุรายการที่ไม่ซ้ำกัน ไม่เป็นทศนิยม และไม่เป็นค่าลบ คุณสามารถคำนวณจากค่า Qcode.code ได้โดยตรง
- ตรวจทานตรรกะและเนื้อหาของแบบสำรวจทั้งหมดได้อย่างง่ายดาย
- มีคุณลักษณะใหม่คือแสดงตรรกะของแบบสำรวจ (Show Survey Logic) ที่ช่วยให้คุณเห็นทุกอย่างเกี่ยวกับแบบสำรวจ (หรือกลุ่มหรือคำถาม) ในหน้าเดียว
- แสดงรายละเอียดระดับกลุ่ม คำถาม คำถามย่อย และคำตอบ สำหรับขอบเขตที่เลือก (แบบสำรวจ กลุ่ม หรือคำถาม)
- ยังแสดงความสัมพันธ์กัน ความสัมพันธ์กันระดับคำถามย่อย (สำหรับ array_filter และ array_filter_exclude) สมการการตรวจสอบที่สร้างขึ้น (สำหรับ preg และกฎการตรวจสอบใด ๆ เช่น ผลรวม/จำนวนค่าขั้นต่ำ/สูงสุด) และคุณสมบัติคำถามทั้งหมดที่ไม่ว่างเปล่า
- ทุกอย่างมีการเน้นไวยากรณ์ เพื่อให้คุณเห็นข้อผิดพลาดทางไวยากรณ์ที่อาจเกิดขึ้น (เช่น วงเล็บไม่ครบคู่ หรือใช้ตัวแปรก่อนที่จะประกาศ)
- การเน้นไวยากรณ์ช่วยให้นำทางและแก้ไขแบบสำรวจได้อย่างรวดเร็ว
- หากคุณคลิกที่ชื่อตัวแปร จะเปิดหน้าต่าง (หรือแท็บ) ของเบราว์เซอร์ที่แสดงคำถามนั้นและให้คุณแก้ไขได้
- หากคุณคลิกที่ชื่อกลุ่ม จะเปิดหน้าต่าง (หรือแท็บ) ของเบราว์เซอร์ที่แสดงมุมมองเรียงลำดับกลุ่มใหม่ เพื่อให้คุณย้ายคำถามได้อย่างง่ายดาย
- คุณสมบัติคำถามทั้งหมดก็มีการเน้นไวยากรณ์เช่นกัน ซึ่งช่วยให้คุณตั้งค่าและดูนิพจน์ภายในตัวเลือกคำถามขั้นสูงได้ (เช่น กำหนดจำนวน/ผลรวมของค่าสูงสุด/ต่ำสุดตามนิพจน์)
- ผู้พัฒนา EM ใช้มุมมองที่คล้ายกัน (สะอาดตากว่าเล็กน้อย) เพื่อให้นักระบาดวิทยาที่ร่วมงานและคณะกรรมการจริยธรรมการวิจัยตรวจสอบและอนุมัติแบบสำรวจที่มีคำถามนับพันข้อในการสัมภาษณ์เชิงโครงสร้างที่มีการแตกสาขาและการปรับแต่งข้อความสูง
เริ่มต้นใช้งาน
วิธีที่ดีที่สุดในการเริ่มต้นใช้งาน EM คือ:
- ติดตั้งเวอร์ชันเสถียรล่าสุดจาก http://www.limesurvey.org/en/download
- นำเข้าและสำรวจแบบสำรวจตัวอย่าง
- สำรวจกรณีการใช้งานและวิธีทำและตัวอย่างทีละขั้นตอน
- สำรวจเอกสารประกอบของ EM (หน้านี้)
- ตรวจสอบชุดทดสอบ EM ที่มีให้ในตัว
- จากแบบสำรวจใดก็ได้ ภายใต้เครื่องมือ ให้เลือกตัวเลือก EM
- ฟังก์ชั่นที่มีอยู่ แสดงรายการฟังก์ชันกว่า 70 รายการและไวยากรณ์
- การทดสอบหน่วยของนิพจน์แบบแยกเดี่ยว
- แสดงตัวอย่างการใช้ฟังก์ชันและตัวดำเนินการทั้งหมดของ EM รวมถึงผลลัพธ์ใน PHP และ JavaScript
- โปรดทราบว่ามีบางฟังก์ชันที่ให้ผลลัพธ์ต่างกันระหว่างเวอร์ชัน PHP และ JavaScript หน้านี้จึงช่วยให้คุณวางแผนตรรกะ EM ได้อย่างเหมาะสม
Expression Manager ขยาย/แทนที่ฟังก์ชันการทำงานใดบ้าง? (LimeSurvey <= 1.91+)
เงื่อนไข => ความสัมพันธ์กัน
เงื่อนไขใช้ควบคุมว่าคำถามใดแสดงหรือไม่ ไวยากรณ์ทั่วไปคือ SGQA operator Value เช่น 111X2X3 == "Y" เงื่อนไขสามารถเชื่อมกันด้วย AND หรือ OR ได้ แต่การผสม AND และ OR เข้าด้วยกันทำได้ยาก ตัวเงื่อนไขเองถูกจัดเก็บในตารางแยกต่างหาก และโค้ดส่วนใหญ่ของ LimeSurvey ถูกใช้ไปกับการจัดการเงื่อนไข เนื่องจากมีการเข้าถึงฐานข้อมูลอย่างหนัก การประมวลผลเงื่อนไขจำนวนมากจึงอาจทำให้ประสิทธิภาพลดลงอย่างเห็นได้ชัด นอกจากนี้ เมื่อคุณกำหนดเงื่อนไขให้กับคำถามหรือกลุ่มแล้ว คุณมักจะไม่สามารถเรียงลำดับใหม่หรือลบคำถามหรือกลุ่มเหล่านั้นได้
การประเมิน => สมการและ Micro-Tailoring
การประเมินช่วยให้ผู้ใช้สร้างคะแนนมาตราส่วนจากกลุ่มของคำถาม อย่างไรก็ตาม คะแนนเหล่านี้ไม่สามารถเปลี่ยนแปลงแบบไดนามิกในหน้าปัจจุบันได้ และค่าของคะแนนไม่ได้ถูกจัดเก็บลงในฐานข้อมูล
การแทนที่ => Micro-Tailoring
ผู้ใช้สามารถปรับแต่งข้อความและคำถามบางส่วนตามคำตอบก่อนหน้าได้ ตัวอย่างเช่น คำถามอาจเป็น {TOKEN:FIRSTNAME}, you said {SPORT.shown} was your favorite sport อย่างไรก็ตาม ไม่สามารถปรับแต่งข้อความแบบมีเงื่อนไขได้ (เช่น ระบุ "Mr." หรือ "Mrs." ตามเพศของบุคคล) หรือการผันคำกริยาและคำนามโดยไม่ใช้ JavaScript ขั้นสูง ผู้เขียนแบบสำรวจสามารถทำแบบสำรวจที่ดูเหมือนปรับแต่งคำถามได้ แต่ต้องสร้างคำถามแยกสำหรับแต่ละรูปแบบที่เป็นไปได้ และต้องใช้เงื่อนไขที่ซับซ้อนเพื่อตัดสินใจว่าจะแสดงคำถามใด
การตรวจสอบ
คำถามสามารถตรวจสอบได้ด้วยนิพจน์ทั่วไป (Regular expression) หรือค่าต่ำสุด/สูงสุด หรือให้คำตอบหนึ่งทำหน้าที่เป็นค่าต่ำสุดหรือสูงสุด อย่างไรก็ตาม การตรวจสอบไม่สามารถอิงจากการคำนวณของตัวแปรอื่นได้ หากไม่ใช้ JavaScript ขั้นสูง
สมการ
ไม่รองรับสมการหากไม่ใช้ JavaScript ขั้นสูง
ประเภทคำถามสมการ
ไม่สามารถบันทึกสมการลงในฐานข้อมูลได้ (เช่น คะแนนสุดท้ายของการประเมิน) หากไม่ใช้ JavaScript ขั้นสูง
Expression Manager จะแทนที่/ขยายฟังก์ชันการทำงานนั้นอย่างไร?
Expression Manager เป็นโมดูลหลักใหม่ใน LimeSurvey ที่ทำให้การรองรับฟังก์ชันการทำงานที่ซับซ้อน ซึ่งแต่ก่อนต้องใช้ JavaScript ที่เขียนขึ้นเองนั้น ง่ายขึ้นมาก นอกจากนี้ยังเข้ามาแทนที่วิธีที่ LimeSurvey จัดการเงื่อนไขและการประเมินในปัจจุบันด้วย
คำศัพท์ใหม่เมื่ออ้างถึง Expression Manager (EM)
EM "คิด" เกี่ยวกับฟังก์ชันการทำงานของตนด้วยคำศัพท์ต่อไปนี้:
- การแตกสาขาตามความสัมพันธ์กัน (Relevance-based Branching) - หากคำถามเกี่ยวข้อง ก็จะถามคำถามนั้น มิฉะนั้นจะไม่ถาม (เช่น ทำให้มองไม่เห็น และทำเครื่องหมายเป็น NULL ในฐานข้อมูล) มีฟิลด์ความสัมพันธ์กันใหม่สำหรับคำถามทุกประเภท และสำหรับแต่ละกลุ่มด้วย (คุณจึงสามารถใช้ชุดเงื่อนไขกับทั้งกลุ่มได้โดยไม่ต้องคัดลอกเงื่อนไขเดียวกันไปยังแต่ละคำถาม และ/หรือรวมตรรกะเงื่อนไขระดับกลุ่มและระดับคำถามเข้าด้วยกัน)
- การปรับแต่งข้อความ (Tailoring) - เมื่อคุณทราบแล้วว่าควรถามคำถามใด การปรับแต่งข้อความ (บางครั้งเรียกว่า piping) จะระบุว่าควรถามคำถามนั้นอย่างไร ซึ่งช่วยให้คุณรองรับได้ไม่เพียงการแทนที่แบบง่าย (เช่น {TOKEN:FIRSTNAME}) แต่ยังรวมถึงการผันคำกริยาและคำนามตามเพศหรือจำนวนของผู้ตอบ และยังช่วยให้คุณเปลี่ยนข้อความที่ส่งถึงผู้ตอบตามว่าพวกเขาตอบ (หรือตอบอย่างไร) คำถามอื่น ๆ
- สมการ (Equations) - EM เพิ่มประเภทคำถามใหม่ที่เรียกว่าสมการ ซึ่งเก็บผลลัพธ์ของนิพจน์ ผลลัพธ์ของสมการเหล่านี้จะถูกคำนวณและเขียนลงในฐานข้อมูล แม้ว่าคุณจะซ่อนไว้ในหน้าก็ตาม ดังนั้นจึงมีประโยชน์สำหรับการคำนวณคะแนนที่ซ่อนอยู่ การนำทางตามสมการที่ซับซ้อน การประเมิน และรายงานที่ควรสร้างขึ้นและพร้อมใช้งานในฐานข้อมูลได้อย่างง่ายดาย
ความสัมพันธ์กันและความสัมพันธ์กันแบบต่อเนื่อง (Cascading Relevance)
ตอนนี้ประเภทคำถามทุกประเภทมีตัวเลือกความสัมพันธ์กันที่ควบคุมว่าจะแสดงคำถามหรือไม่ EM ประมวลผลสมการความสัมพันธ์กันแต่ละสมการตามลำดับที่ควรปรากฏในแบบสำรวจ หากนิพจน์เป็นจริง (หรือไม่มี - เพื่อรองรับแบบสำรวจรุ่นเก่า) คำถามจะถูกแสดง หากไม่เกี่ยวข้อง คำถามจะถูกซ่อน และค่าจะถูกตั้งเป็น NULL ในฐานข้อมูล หากไม่มีคำถามที่เกี่ยวข้องในกลุ่ม กลุ่มทั้งหมดจะถูกข้ามไป
นอกจากนี้ หากตัวแปรใดในนิพจน์ไม่เกี่ยวข้อง นิพจน์นั้นจะประเมินค่าเป็นเท็จเสมอ ซึ่งทำให้เกิดความสัมพันธ์กันแบบต่อเนื่อง คุณจึงไม่ต้องเขียนสมการความสัมพันธ์กันที่ยาวมากสำหรับแต่ละคำถาม
สมมติว่าคุณมีคำถาม 5 ข้อ คือ Q1-Q5 และคุณต้องการแสดง Q2 เฉพาะเมื่อมีการตอบ Q1 และแสดง Q3 เฉพาะเมื่อมีการตอบ Q2 เป็นต้น สมการความสัมพันธ์กันอาจเป็นดังนี้:
| รหัสคำถาม | ความสัมพันธ์กัน | คำถาม |
|---|---|---|
| Q1 | 1 | คุณชื่ออะไร? |
| Q2 | Q1 | {Q1} คุณอายุเท่าไร? |
| Q3 | Q2 | คุณอายุ {Q2} ปี คุณแต่งงานแล้วหรือไม่? |
| Q4 | Q3 == "Y" | {Q1} คุณแต่งงานมานานเท่าไรแล้ว? |
| Q5 | Q4 | {Q1} คุณมีบุตรกี่คน? |
การคำนวณความสัมพันธ์กันยังทำงานใน JavaScript ด้วย ดังนั้นคุณสามารถใส่คำถามทั้งหมดข้างต้นไว้ในหน้าเดียวและยังคงทำงานได้ตามที่คาดไว้ อันที่จริง EM เข้ามาแทนที่วิธีที่ใช้ประมวลผลรูปแบบแบบสำรวจแบบทั้งแบบสำรวจ แบบทีละกลุ่ม และแบบทีละคำถามโดยสิ้นเชิง ตอนนี้ทั้งหมดใช้เอนจินการนำทางเดียวกัน จึงทำงานเหมือนกันไม่ว่าจะเป็นรูปแบบแบบสำรวจใดก็ตาม
ตราบใดที่คุณยังอยู่ในหน้าเดียวกัน ข้อมูลที่คุณป้อนไว้จะยังคงอยู่ เพียงแต่ถูกซ่อน ดังนั้น หากคุณป้อนข้อมูลบางอย่าง แล้วเลือกตัวเลือกที่ทำให้ข้อมูลนั้นไม่เกี่ยวข้อง จากนั้นทำให้เกี่ยวข้องอีกครั้ง คำตอบของคุณจะยังคงอยู่ อย่างไรก็ตาม ทันทีที่คุณย้ายไปยังหน้าอื่น การตอบคำถามที่ไม่เกี่ยวข้องทั้งหมดจะสูญหายไปเพื่อรักษาความสมบูรณ์ของชุดข้อมูล
ความสัมพันธ์กันระดับกลุ่ม
Expression Manager ยังรองรับความสัมพันธ์กัน (relevance) ในระดับกลุ่มด้วย ซึ่งช่วยให้ใช้งานการวนซ้ำได้ง่ายขึ้น สมมติว่าคุณต้องการเก็บข้อมูลของรายการได้สูงสุด 10 รายการ (เช่น ผลิตภัณฑ์หรือสมาชิกในครัวเรือน) โดยก่อนอื่นคุณต้องทราบว่ามีกี่รายการที่ต้องถามต่อ (เช่น ถามว่ามีสมาชิกในครัวเรือนกี่คน หรือให้ผู้ตอบเลือกผลิตภัณฑ์ที่ชอบจากรายการยาว) เมื่อทราบจำนวนรายการที่ต้องถามต่อแล้ว คุณสามารถใช้ความสัมพันธ์กันระดับกลุ่ม เช่น {count >= 1}, {count >=2}, ... {count >= 10} สำหรับกลุ่มคำถามต่อเนื่องทั้ง 10 กลุ่ม ภายในแต่ละกลุ่ม คุณสามารถกำหนดตรรกะเงื่อนไขระดับคำถามได้ (เช่น คำถามต่อเนื่องที่เฉพาะเจาะจงตามเพศหรืออายุของแต่ละคน) สมการความสัมพันธ์กันระดับคำถามและระดับกลุ่มจะถูกนำมารวมกันด้วย AND เพื่อกำหนดว่าจะแสดงคำถามใด
การปรับแต่งข้อความ / Piping
ข้อความใดก็ตามที่อยู่ในวงเล็บปีกกาจะถูกถือว่าเป็นนิพจน์ (มีข้อยกเว้นหนึ่งข้อตามที่อธิบายด้านล่าง) นิพจน์สามารถเข้าถึง LimeReplacementFields ทั้งหมด ตัวแปรทั้งหมด (ผ่านชื่อแทนหลายแบบ) ตัวดำเนินการสมการทั่วไปทั้งหมด (ทางคณิตศาสตร์ ตรรกะ และการเปรียบเทียบ) และฟังก์ชันอีกหลายสิบรายการ (ซึ่งทำงานแบบไดนามิกฝั่งไคลเอนต์ได้ด้วย)
เมื่อใช้สมการเหล่านี้ คุณสามารถทำสิ่งต่าง ๆ ได้ เช่น
- แสดงข้อความที่ปรับแต่งให้ผู้ตอบตามเงื่อนไข โดยอิงจากการตอบคำถามก่อนหน้า
- สร้างการประเมิน และแสดงผลการประเมิน (หรือแตกสาขาหรือแสดงข้อความตามเงื่อนไข) ตามผลลัพธ์เหล่านั้น โดยไม่ต้องใช้โมดูลการประเมินเลย
- ผันคำกริยาและเปลี่ยนรูปคำนามภายในคำถาม คำตอบ และรายงาน
- แสดงสรุปการตอบคำถามก่อนหน้าหน้า "Show your answers" ที่ท้ายแบบสำรวจ
สมการ
มีคำถามประเภทใหม่ชื่อสมการ (Equation) ซึ่งคล้ายกับคำถามแบบ Boilerplate ยกเว้นว่าจะจัดเก็บค่าของสิ่งที่แสดงไว้ลงในฐานข้อมูล ดังนั้น หากข้อความคำถามของสมการมีการคำนวณการประเมิน ค่านั้นจะถูกจัดเก็บในฐานข้อมูลเป็นตัวแปรที่สามารถแสดงในสถิติสาธารณะหรือสถิติส่วนตัวได้
วิธีนี้ตอบโจทย์คำขอที่พบบ่อยในการจัดเก็บคะแนนการประเมินไว้ในฐานข้อมูล
ไวยากรณ์
ข้อความใดก็ตามที่อยู่ภายในวงเล็บปีกกาจะถูกถือว่าเป็นนิพจน์ (มีข้อยกเว้นหนึ่งข้อ คือ ต้องไม่มีช่องว่างนำหน้าหรือตามหลัง ซึ่งจำเป็นเพื่อให้ Expression Manager ไม่พยายามประมวลผล JavaScript ที่ฝังอยู่)
หมายเหตุ นิพจน์สามารถเขียนหลายบรรทัดได้ ตราบเท่าที่ไม่มีช่องว่างหลังวงเล็บปีกกาเปิดหรือก่อนวงเล็บปีกกาปิด ซึ่งเป็นประโยชน์อย่างยิ่งสำหรับคำสั่ง if() ซ้อนกัน ดังตัวอย่างนี้:
{if(is_empty(PFTotals),
'',
if(PFTotals >= -5 && PFTotals <= -4,
'Very Soft',
if(PFTotals >= -3 && PFTotals <= -2,
'Soft',
if(PFTotals == -1,
'Somewhat Soft',
if(PFTotals == 0,
'Moderate',
if(PFTotals == 1,
'Somewhat Hard',
if(PFTotals >= 2 && PFTotals <= 3,
'Hard',
if(PFTotals >= 4 && PFTotals <= 5,
'Very Hard',
''
)
)
)
)
)
)
)
)}
- ตัวดำเนินการทางคณิตศาสตร์มาตรฐานทั้งหมด (เช่น +,-,*,/,!)
- ตัวดำเนินการเปรียบเทียบมาตรฐานทั้งหมด (เช่น <,<=,==,!=,>,>=, รวมถึงตัวดำเนินการที่เทียบเท่ากัน: lt,le,eq,ne,gt,ge)
- วงเล็บ (สำหรับจัดกลุ่มนิพจน์ย่อย)
- ตัวดำเนินการเงื่อนไข (เช่น &&,| | และตัวดำเนินการที่เทียบเท่ากัน: and,or)
- สตริงที่อยู่ในเครื่องหมายคำพูดเดี่ยวและคู่ (ซึ่งแต่ละแบบสามารถฝังสตริงที่ใช้เครื่องหมายคำพูดอีกแบบได้)
- ตัวดำเนินการคอมมา (ทำให้มีรายการนิพจน์ได้และคืนค่าเฉพาะผลลัพธ์สุดท้าย)
- ตัวดำเนินการกำหนดค่า (=)
- ตัวแปรที่กำหนดไว้ล่วงหน้า (ใช้อ้างอิงคำถาม คุณสมบัติคำถาม และการตอบคำถาม) เช่น รหัส SGQA ทั้งหมด
- ฟังก์ชันที่กำหนดไว้ล่วงหน้า (ปัจจุบันมีมากกว่า 70 รายการ และเพิ่มได้ง่าย)
ตัวดำเนินการ
ไวยากรณ์ของ EM เป็นไปตามลำดับความสำคัญของตัวดำเนินการตามปกติ:
| ระดับ | ตัวดำเนินการ | คำอธิบาย |
|---|---|---|
| 1 | () | วงเล็บสำหรับจัดกลุ่มหรือเรียกใช้ฟังก์ชัน |
| 2 | ! - + | ตัวดำเนินการเอกภาค: not, การเปลี่ยนเครื่องหมาย, เครื่องหมายบวก |
| 3 | * / | คูณ, หาร |
| 4 | + - | บวก, ลบ |
| 5 | < <= > >= lt le gt ge | การเปรียบเทียบเชิงสัมพัทธ์ |
| 6 | == != eq ne | การเปรียบเทียบความเท่ากัน |
| 7 | and | AND เชิงตรรกะ |
| 8 | or | OR เชิงตรรกะ |
| 9 | = | ตัวดำเนินการกำหนดค่า |
| 10 | , | ตัวดำเนินการคอมมา |
คำเตือนเกี่ยวกับตัวดำเนินการบวก (+)
เพื่อให้ JavaScript และ PHP ทำงานสอดคล้องกัน ตัวดำเนินการบวก (+) จะทำการบวกเมื่อตัวถูกดำเนินการทั้งสองเป็นตัวเลข แต่จะทำการต่อสตริงเมื่อทั้งสองส่วนเป็นสตริงที่ไม่ใช่ตัวเลข อย่างไรก็ตาม เราแนะนำให้ใช้ฟังก์ชัน join() สำหรับการต่อสตริง และฟังก์ชัน sum() สำหรับการบวก เนื่องจากทำให้เจตนาของคุณชัดเจนยิ่งขึ้น และหลีกเลี่ยงผลลัพธ์ที่ไม่คาดคิดในกรณีที่คุณคาดว่าจะได้สตริงแต่ได้ตัวเลข (หรือในทางกลับกัน)
คำเตือนเกี่ยวกับความไม่ตรงกันระหว่างตัวเลขกับสตริง และการเปรียบเทียบตามตัวอักษร
เมื่อคุณต้องการเปรียบเทียบค่าด้วยการเปรียบเทียบเชิงสัมพัทธ์หรือความเท่ากัน โปรดระวังเรื่องความไม่ตรงกันของชนิดข้อมูล ค่าที่ผู้ใช้กรอกหรือรหัสคำตอบที่เลือกสามารถใช้เป็นตัวเลขได้หากเป็นตัวเลขอย่างชัดเจน
หากคุณใส่เครื่องหมาย " ล้อมรอบค่าใดค่าหนึ่ง ระบบจะบังคับให้เปรียบเทียบเป็นข้อความ (เปรียบเทียบตามตัวอักษร) หากต้องการเปรียบเทียบเชิงตัวเลข อย่าใส่เครื่องหมายคำพูด " ล้อมรอบตัวเลขเด็ดขาด
ตัวอย่างเช่น Q0.NAOK > "50" จะเป็นจริงหาก Q0.NAOK เป็นคำถามตัวเลขที่มีค่าเป็น 9 เนื่องจากตัวดำเนินการ > จะถือว่าเป็นการเปรียบเทียบตามตัวอักษร ไม่ใช่เชิงตัวเลข
เพื่อให้แน่ใจว่าเปรียบเทียบค่าจำนวนเต็ม คุณสามารถใช้ intval(Q0.NAOK) > 50 โปรดจำไว้ว่าหาก Q0.NAOK ไม่ใช่ตัวเลข (ว่างหรือเป็นสตริง) intval(Q0.NAOK) จะเท่ากับ 0 หากต้องการเปรียบเทียบค่าสตริง ("A" < "B") ให้ใช้ strcmp โดยตรง: strcmp(Q0.NAOK,"B") หรือ strcmp(Q0.NAOK,"A5")
ข้อควรระวังในการใช้ตัวดำเนินการกำหนดค่า (=)
หมายเหตุ คุณควรหลีกเลี่ยงการใช้ตัวดำเนินการกำหนดค่า เว้นแต่จะจำเป็นจริง ๆ เนื่องจากอาจทำให้เกิดผลข้างเคียงที่ไม่คาดคิด ตัวอย่างเช่น หากคุณเปลี่ยนค่าของการตอบคำถามก่อนหน้า ตรรกะความสัมพันธ์กันแบบต่อเนื่องและตรรกะการตรวจสอบระหว่างคำถามนั้นกับคำถามปัจจุบันจะไม่ถูกคำนวณใหม่ ทำให้คุณอาจได้ข้อมูลที่ขัดแย้งกันเอง (เช่น คำถามที่ยังคงมีคำตอบแต่ควรเป็น NULL หรือคำถามที่ถูกข้ามแต่ควรได้รับคำตอบ) โดยทั่วไป หากต้องการกำหนดค่าให้ตัวแปร คุณควรสร้างคำถามประเภทสมการ แล้วใช้นิพจน์เพื่อกำหนดค่า อย่างไรก็ตาม มีบางครั้งที่ผู้ใช้จำเป็นต้องใช้ตัวดำเนินการนี้จริง ๆ เราจึงเปิดให้ใช้งานได้
เพื่อเตือนให้ระมัดระวังเกี่ยวกับตัวดำเนินการนี้ ระบบจะแสดงตัวดำเนินการนี้เป็นตัวอักษรสีแดงภายในสมการที่เน้นไวยากรณ์ (เพื่อไม่ให้สับสนกับ "==")
การใช้ตัวดำเนินการกำหนดค่า
เหตุผลหลักที่คุณอาจต้องการใช้การกำหนดค่า ได้แก่:
- คุณต้องการตั้งค่าเริ่มต้นให้กับคำถามที่ไม่รองรับค่าเริ่มต้นผ่านสมการ (เช่น รายการแบบปุ่มตัวเลือก ซึ่งส่วนติดต่อผู้ใช้ให้เลือกหนึ่งในตัวเลือกของคำตอบ แต่ไม่ให้ป้อนสมการ) อย่างไรก็ตาม โปรดระมัดระวัง เนื่องจาก LimeSurvey จะไม่สามารถตรวจสอบได้ว่าสมการของคุณให้ผลเป็นหนึ่งในคำตอบที่อนุญาตสำหรับคำถามนั้นหรือไม่
- คุณต้องการบังคับเปลี่ยนการตอบคำถามก่อนหน้าโดยอิงจากการตอบคำถามที่ตามมาภายหลัง
- คุณต้องการโควตาที่ซับซ้อน: โดยใช้คำถามแบบตัวเลือกเดียวที่ซ่อนอยู่สำหรับโควตา และกำหนดค่าด้วยการกำหนดค่า
- ฯลฯ
คุณสามารถใช้ระบบ Expression Manager ทั้งหมดเพื่อวัตถุประสงค์นี้ได้
ตัวอย่าง:
- กำหนดคำตอบของคำถามข้อความสั้นให้เป็นตัวพิมพ์เล็ก :
{QCODE=strtolower(QCODE.NAOK)} - กำหนดคำตอบเริ่มต้นให้กับคำถามประเภทอาร์เรย์ที่จุดเริ่มต้นของแบบสำรวจ :
{Q1_SQ1=((is_empty(Q1_SQ1.NAOK),"A99",Q1_SQ1.NAOK)} - กำหนดคำตอบเริ่มต้นให้กับคำถามประเภทอาร์เรย์ข้อความที่จุดเริ่มต้นของแบบสำรวจ :
{Q1_SQY1_SQX1 = ((is_empty(Q1_SQY1_SQX1.NAOK),"Inserted answer", Q1_SQY1_SQX1.NAOK)} - กำหนดคำตอบตามเงื่อนไข :
{QCODE=if(YesNo="Y","A1","")}
ความปลอดภัย XSS
เมื่อเปิดใช้งาน XSS จะไม่สามารถใช้ฟีเจอร์บางอย่างของ Expression Manager ได้ ดังนี้:
- การเริ่มแท็ก HTML ในนิพจน์หนึ่งแต่ไปปิดในอีกนิพจน์หนึ่ง
- การใช้นิพจน์ที่ซับซ้อนใน URL
ตัวอย่างและวิธีแก้ไข
{if( 1 ,"<strong>","")}information{if( 1 ,"</strong>","")}ใช้งานไม่ได้เมื่อเปิดใช้ความปลอดภัย XSS ในกรณีนี้คุณสามารถใช้{if(1,"<strong>information</strong>","information")}<a href="/script.php?value={if(QCODE == "Y","yes","no")}">next</a>ในกรณีนี้คุณสามารถใช้คำถามประเภทสมการ เพราะการใช้รหัสคำถามแบบสมบูรณ์ทำได้ :<a href="/script.php?value={EQUATION.NAOK}">next</a>
การเข้าถึงตัวแปร
Expression Manager ให้สิทธิ์เข้าถึงตัวแปรที่เราอาจต้องการแบบอ่านอย่างเดียว เพื่อความเข้ากันได้กับเวอร์ชันเก่า จึงรองรับการเข้าถึงต่อไปนี้:
- TOKEN:xxx - ค่าของ TOKEN (เช่น TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (ใช้ได้เฉพาะแบบสำรวจที่ไม่ได้ไม่ระบุตัวตน)
- QCODE.shown - ค่าที่แสดงของคำตอบ (เช่น "ใช่") โดยใช้ Expression Manager
- ค่า {XXX} ทั้งหมดที่ใช้โดยเทมเพลต
- ในข้อความคำถาม คุณสามารถใช้ {QID} ซึ่งจะถูกแทนที่ด้วยหมายเลขคำถาม และ {SGQ} ซึ่งจะถูกแทนที่ด้วย SGQA ของคำถาม
นอกจากนี้ Expression Manager ยังให้คุณอ้างอิงตัวแปรด้วยรหัสคำถาม (คอลัมน์ 'title' ในตารางคำถามภายในฐานข้อมูล) ซึ่งเป็นป้ายชื่อตัวแปรที่ใช้เมื่อคุณส่งออกข้อมูลไปยัง SPSS, R หรือ SAS ตัวอย่างเช่น หากคุณมีคำถามเกี่ยวกับชื่อ อายุ และเพศ คุณสามารถเรียกตัวแปรเหล่านั้นว่า name, age และ gender แทน 12345X13X22, 12345X13X23 และ 12345X13X24 ซึ่งทำให้ทุกคนอ่านสมการและตรวจสอบตรรกะได้ง่ายขึ้น และยังสามารถสลับตำแหน่งคำถามได้โดยไม่ต้องคอยติดตามหมายเลขกลุ่มหรือหมายเลขคำถาม
สำคัญ: การอ้างอิงตัวแปรที่อยู่ในหน้าหรือคำถามก่อนหน้าเท่านั้นจึงจะปลอดภัย
นอกจากนี้ Expression Manager ยังให้คุณเข้าถึงคุณสมบัติหลายอย่างของคำถามได้:
| ไวยากรณ์ | ความหมาย | ตัวอย่าง | ผลลัพธ์ตัวอย่าง |
|---|---|---|---|
| Qcode | ชื่อแทนของ Qcode.code | {implode(',',name,gender)} | 'Tom','M' |
| Qcode.code | รหัสคำตอบที่เลือกสำหรับคำถามหากคำถามนั้นมีความสัมพันธ์กัน (มิฉะนั้นจะว่าง) หรือค่าข้อความหากไม่ใช่คำถามแบบมีรหัส | {implode(',',name.code,gender.code)} | 'Tom','M' |
| Qcode.NAOK | เหมือนกับ Qcode - ดูคำอธิบายเกี่ยวกับ NAOK | {gender.NAOK} | 'M' |
| Qcode.value | ค่าการประเมินของคำถามหากคำถามนั้นมีความสัมพันธ์กัน (มิฉะนั้นจะว่าง) หรือค่าข้อความหากไม่ใช่คำถามแบบมีรหัส | {gender.value} | '1' |
| Qcode.valueNAOK | เหมือนกับ Qcode.value - ดูคำอธิบายเกี่ยวกับ NAOK | {gender.valueNAOK} | '1' |
| Qcode.shown | ค่าที่แสดงของคำถาม | {implode(',',name.shown,gender.shown)} | 'Tom','Male' |
| Qcode.question | ข้อความของคำถาม | {gender.question} | 'What is your gender?' |
| Qcode.mandatory | คำถามจำเป็นต้องตอบหรือไม่ (Y/N) | {gender.mandatory} | 'N' |
| Qcode.qid | หมายเลขคำถามภายใน (ไม่ใช่ลำดับที่) | {gender.qid} | 337 |
| Qcode.type | ประเภทคำถาม | {gender.type} | 'G' |
| Qcode.jsName | ชื่อ JavaScript ที่ถูกต้องของคำถาม ไม่ว่าจะประกาศไว้ในหน้านี้หรือหน้าอื่น | {gender.jsName} | 'java1827X3X337' |
| Qcode.gid | หมายเลขกลุ่มภายใน (ไม่ใช่ลำดับที่) | {gender.gid} | 3 |
| Qcode.qseq | ลำดับที่ของคำถาม เริ่มจาก 0 | {gender.qseq} | 5 |
| Qcode.gseq | ลำดับที่ของกลุ่ม เริ่มจาก 0 | {gender.gseq} | 1 |
| Qcode.relevanceStatus | คำถามมีความสัมพันธ์กันในขณะนี้หรือไม่ (0 หรือ 1) | {gender.relevanceStatus} | 1 |
| Qcode.relevance | สมการความสัมพันธ์กันระดับคำถาม | {gender.relevance} | '!is_empty(name)' |
| Qcode.grelevance | สมการความสัมพันธ์กันระดับกลุ่ม | {gender.grelevance} | 'num_children >= 5' |
| Qcode.sgqa | ค่า SGQA ของคำถามนี้ | {gender.sgqa} | '1827X3X337' |
ปัญหาเกี่ยวกับตัวแก้ไข HTML
หากคุณใช้ตัวแก้ไข HTML อักขระบางตัวจะถูกแทนที่ด้วย HTML entity
- & เป็น &
- < เป็น <
- > เป็น >
หากคุณใช้ตัวแก้ไข HTML คุณต้องใช้:
- and แทน &
- lt แทน <
- le แทน <=
- gt แทน >
- ge แทน >=
การตั้งชื่อตัวแปร Qcode
นี่คือรายละเอียดวิธีสร้าง Qcode (และการเข้าถึงคุณสมบัติบางอย่าง) ตามประเภทคำถาม โดยทั่วไป Qcode จะถูกสร้างดังนี้:
QuestionCode . '_' . SubQuestionCode . '_' . ScaleId
ต้องใช้รหัสคำถามย่อยและ Scale ID หรือไม่ขึ้นอยู่กับประเภทคำถาม - ดูตารางด้านล่าง สำหรับ comment และ other รหัสคำถามคือ QuestionCode_comment และ QuestionCode_other
| ประเภท | คำอธิบาย | รหัส | คำถามย่อย | ตัวเลือกของคำตอบ | มาตราส่วน | รหัสคำตอบ | คำตอบที่แสดง | ความสัมพันธ์กัน |
|---|---|---|---|---|---|---|---|---|
| 5 | ตัวเลือก 5 คะแนน แบบปุ่มตัวเลือก | Q1 | 1-5 | {Q1} | {Q1.shown} | {Q1==3} | ||
| B | อาร์เรย์ (ตัวเลือก 10 คะแนน) แบบปุ่มตัวเลือก | Q2 | L1-L6 | 1-10 | {Q2_L2} | {Q2_L2.shown} | {Q2_L2==7} | |
| A | อาร์เรย์ ((ตัวเลือก 5 คะแนน)) แบบปุ่มตัวเลือก | Q3 | 1-5 | 1-5 | {Q3_1} | {Q3_1.shown} | {Q3_1>=3} | |
| 1 | อาร์เรย์ (ลาเบลแบบยืดหยุ่น) มาตราส่วนคู่ | Q4 | sq1-sq5 | 0:a1-a3 | 1:b1-b3 | {Q4_sq1_0} | {Q4_sq1_1.shown} | {Q4_sq1_1=='b2'} |
| H | อาร์เรย์ (แบบยืดหยุ่น) - รูปแบบคอลัมน์ | Q5 | 1-5 | s,m,t | {Q5_1} | {Q5_1.shown} | {Q5_1=='s'} | |
| F | อาร์เรย์ (แบบยืดหยุ่น) - รูปแบบแถว | Q6 | F1-F5 | 1-5 | {Q6_F3} | {Q6_F3.shown} | {Q6_F3==4} | |
| E | อาร์เรย์ (เพิ่มขึ้น / เท่าเดิม / ลดลง) แบบปุ่มตัวเลือก | Q7 | 1-7 | I,S,D | {Q7_4} | {Q7_4.shown} | {Q7_4=='D'} | |
| : | อาร์เรย์ (Multi Flexi) 1 ถึง 10 | Q8 | ls1,todo,ls2 | min,max,avg | {Q8_ls1_max} | {Q8_ls2_avg.shown} | {Q8_ls2_min==7} | |
| ; | อาร์เรย์ (Multi Flexi) ข้อความ | Q9 | hp,st,sw | 1st,2nd,3rd | {Q9_hp_3rd} | {Q9_hp_3rd.shown} | {Q9_hp_3rd=='Peter'} | |
| C | ตัวเลือก (ใช่/ไม่แน่ใจ/ไม่ใช่) แบบปุ่มตัวเลือก | Q10 | 1-5 | Y,N,U | {Q10_1} | {Q10_1.shown} | {Q10_3=='Y'} | |
| X | คำถามแบบข้อความคงที่ (Boilerplate) | Q11 | {Q11.shown} | |||||
| D | วันที่ | Q12 | {Q12} | {Q12.shown} | ||||
| * | สมการ | Q13 | {Q13} | {Q13.shown} | {Q13>5} | |||
| ~124~ | อัพโหลดไฟล์ (บันทึกจำนวนไฟล์ที่อัปโหลด) | Q14 | {Q14} | {Q14>0} | ||||
| G | รายการเลือกแบบดึงลงสำหรับเพศ | Q15 | M,F | {Q15} | {Q15.shown} | {Q15=='M'} | ||
| U | ข้อความแบบยาวพิเศษ | Q16 | {Q16} | {Q16.shown} | {strlen(Q16)>100} | |||
| I | คำถามภาษา | Q17 | {Q17} | {Q17.shown} | {Q17=='en'} | |||
| ! | รายการ - ดรอปดาวน์ | Q18 | 1-5 | {Q18} | {Q18.shown} | {Q18==3} | ||
| L | รายการแบบดรอปดาวน์/ปุ่มตัวเลือก | Q19 | A-Z | {Q19} | {Q19.shown} | {Q19=='X'} | ||
| O | รายการพร้อมความคิดเห็น แบบดรอปดาวน์/ปุ่มตัวเลือก + พื้นที่ข้อความ | Q20 | A-F | {Q20},{Q20comment} | {Q20.shown} | {Q20=='B'} | ||
| T | ข้อความแบบยาว | Q21 | {Q21} | {Q21.shown} | {strstr(Q21,'hello')>0} | |||
| M | เลือกตอบได้หลายตัว แบบช่องทำเครื่องหมาย | Q22 | A-F, other | {Q22_E}, {Q22_other} | {Q22_E.shown}, {Q22_other.shown} | {Q22_E=='Y'} | ||
| P | เลือกตอบได้หลายตัวพร้อมความคิดเห็น ช่องทำเครื่องหมาย + ข้อความ | Q23 | A-F | {Q23_D}, {Q23_Dcomment} | {Q23_D.shown} | {!is_empty(Q23)} | ||
| K | คำถามตัวเลขหลายรายการ | Q24 | self,mom,dad | {Q24_self} | {Q24_self.shown} | {Q24_self>30} | ||
| Q | ข้อความสั้นหลายรายการ | Q25 | A-F | {Q25_B} | {Q25_B.shown} | {substr(Q25_B,1,1)=='Q'} | ||
| N | คำถามประเภทตัวเลข | Q26 | {Q26} | {Q26.shown} | {Q26 > 30} | |||
| R | รูปแบบการจัดอันดับ | Q27 | 1-4 | {Q27_1} | {Q27_1.shown} | {Q27_1==3} | ||
| S | ข้อความแบบสั้น | Q28 | {Q28} | {Q28.shown} | {Q28=='mine'} | |||
| Y | ใช่/ไม่ใช่ แบบปุ่มตัวเลือก | Q29 | {Q29} | {Q29.shown} | {Q29=='Y'} |
ตัวแปรสงวน 'this', 'self' และ 'that'
บ่อยครั้งที่คุณต้องการประเมินทุกส่วนของคำถาม เช่น นับว่ามีคำถามย่อยที่ตอบแล้วกี่ข้อ หรือรวมคะแนน บางครั้งคุณต้องการประมวลผลเฉพาะบางแถวหรือบางคอลัมน์ของคำถาม (เช่น หาผลรวมของแถวหรือคอลัมน์แล้วเก็บลงฐานข้อมูล) ตัวแปรสงวนเหล่านี้ช่วยให้ขั้นตอนดังกล่าวทำได้ง่ายขึ้นมาก
ตัวแปร 'this' ใช้เฉพาะในตัวเลือกขั้นสูงของคำถาม "Whole question validation equation" และ "Sub-question validation equation" เท่านั้น โดยจะขยายเป็นชื่อตัวแปรของแต่ละเซลล์ภายในคำถามเหล่านั้น ดังนั้น หากคุณต้องการให้แต่ละรายการมีค่ามากกว่าสาม ให้ตั้งค่า "Sub-question validation equation" เป็น (this > 3)
ตัวแปร 'self' และ 'that' มีประสิทธิภาพมากกว่า และทำหน้าที่เป็นแมโครที่ถูกขยายก่อนการประมวลผลสมการ รูปแบบไวยากรณ์ที่ใช้ได้มีดังนี้:
- self
- self.suffix
- self.sub-selector
- self.sub-selector.suffix
suffix คือคำต่อท้ายของ qcode ปกติใดๆ (เช่น NAOK, value, shown)
sub-selector คือหนึ่งในต่อไปนี้:
- comments - เฉพาะคำถามย่อยที่เป็นความคิดเห็น (เช่น จากเลือกตอบได้หลายตัวพร้อมความคิดเห็น และรายการพร้อมความคิดเห็น)
- nocomments - เฉพาะคำถามย่อยที่ไม่ใช่ความคิดเห็น
- sq_X - โดย X คือตัวระบุแถวหรือคอลัมน์ ระบบจะเลือกเฉพาะคำถามย่อยที่ตรงกับรูปแบบ X โปรดทราบว่าการค้นหาจะทำกับตัวระบุรหัสที่สมบูรณ์ จากนั้น sq_X จะจับคู่และรวมคำถามย่อย nX, X, Xn (เช่น หากคุณใช้ sq_1 คำถามย่อย a1, 1a, 1, 11 หรือ 001 จะถูกรวมด้วย) โปรดระวังในคำถามประเภทมาตราส่วนคู่ ซึ่งรหัสคำถามย่อยคือ QCODE_SQCODE_1 และ QCODE_SQCODE_1 และในคำถามประเภทการจัดอันดับ ซึ่งรหัสคำถามย่อยคือ QCODE_1,QCODE_2 ....
- nosq_X - โดย X คือตัวระบุแถวหรือคอลัมน์ ระบบจะเลือกเฉพาะคำถามย่อยที่ไม่ตรงกับรูปแบบ X โปรดทราบว่าการค้นหาจะทำกับตัวระบุรหัสที่สมบูรณ์ จากนั้น nosq_X จะจับคู่และไม่รวมคำถามย่อย nX, X, Xn
ตัวอย่าง:
- มีส่วนใดของคำถามที่ถูกตอบแล้วหรือไม่? {count(self.NAOK)>0}
- คะแนนการประเมินของคำถามนี้คือเท่าใด? {sum(self.value)}
คุณยังสามารถใช้ตัวแปรเหล่านี้เพื่อหาผลรวมของแถวและคอลัมน์ได้ สมมติว่าคุณมีอาร์เรย์ของตัวเลขที่มีแถว A-E และคอลัมน์ 1-5
- ผลรวมสุดท้ายคือเท่าใด? {sum(self.NAOK)}
- ผลรวมของแถว B คือเท่าใด? {sum(self.sq_B.NAOK)}
- ผลรวมของคอลัมน์ 3 คือเท่าใด? {sum(self.sq_3.NAOK)}
ตัวแปร 'that' คล้ายกับตัวแปร 'self' แต่ให้คุณอ้างอิงถึงคำถามอื่นได้ ไวยากรณ์คือ:
- that.qname
- that.qname.suffix
- that.qname.sub-selector
- that.qname.sub-selector.suffix
qname คือชื่อคำถามโดยไม่มีส่วนขยายของคำถามย่อย ดังนั้น หากคุณสร้างคำถาม 'q1' นั่นคือ qname ของคำถามนั้น
ตัวอย่าง:
- มีส่วนใดของคำถาม q1 ที่ถูกตอบแล้วหรือไม่? {count(that.q1.NAOK)>0}
- คะแนนการประเมินของ q2 คือเท่าใด? {sum(that.q2.NAOK)}
- ผลรวมสุดท้ายของ q3 คือเท่าใด? {sum(that.q3.NAOK)}
- ผลรวมของแถว C ใน q4 คือเท่าใด? {sum(that.q4.sq_C.NAOK)}
- ผลรวมของคอลัมน์ 2 ใน q4 คือเท่าใด? {sum(that.q4.sq_2.NAOK)}
ตัวแปร 'self' และ 'that' สามารถใช้ในความสัมพันธ์กัน การตรวจสอบ หรือการปรับแต่งข้อความ (tailoring) ได้ทุกแบบ
ข้อควรระวังอย่างหนึ่งคือ เมื่อคุณใช้ฟีเจอร์ Show Logic File ระบบจะแสดงค่าที่ขยายแล้วของ 'self' และ 'that' ซึ่งช่วยให้คุณเห็นสมการจริงที่จะถูกสร้างขึ้น เพื่อให้คุณ (และ Expression Manager) ตรวจสอบได้ว่าตัวแปรมีอยู่จริง อาจดูสับสนเพราะคุณอาจเห็นสมการที่ยาวมาก อย่างไรก็ตาม หากคุณแก้ไขคำถาม คุณจะเห็นสมการต้นฉบับที่ใช้ 'self' และ/หรือ 'that'
โปรดทราบด้วยว่าไม่ควรใช้ตัวแปรเหล่านี้หาก (ก) คุณต้องการระบุชื่อตัวแปรแต่ละตัวที่ใช้ในสมการอย่างชัดเจน หรือ (ข) ใช้ตัวแปรที่ไม่มีคำถามย่อย (เช่น คำถามแบบตอบได้ครั้งเดียว) ในกรณีเหล่านี้ การใส่ 'that' นำหน้าตัวแปรถือว่าเกินความจำเป็น และอาจทำให้ได้ผลลัพธ์ที่ไม่คาดคิด
การใช้ NAOK
NAOK --> "Not Applicable" (NA) is alright (OK) หรือ "ไม่เกี่ยวข้อง" (NA) ก็ไม่เป็นไร (OK)
การใช้ NAOK หมายความว่าตัวแปรทั้งหมดหรือบางส่วนไม่เกี่ยวข้อง (เช่น "Not Applicable" (NA) ก็ไม่เป็นไร (OK))
เมื่อคุณนำตัวแปรจากคำถามไปใช้ในสมการใด ๆ หากคำถามนี้ (หรือคำถามย่อย) ถูกซ่อนด้วยเงื่อนไข สมการทั้งหมดจะถูกปิดใช้งาน
ตัวอย่างเช่น count(Q1_SQ1,Q1_SQ2,Q1_SQ3,Q1_SQ4) จะให้ค่าเป็นสตริงว่างเสมอ หากคำถามย่อยใดคำถามย่อยหนึ่งของ Q1 ถูกกรองออก การนับจำนวนคำถามย่อยที่ถูกเลือกในคำถามลักษณะนี้ทำได้โดยใช้ count(Q1_SQ1.NAOK,Q1_SQ2.NAOK,Q1_SQ3.NAOK,Q1_SQ4.NAOK) หากคำถามย่อยถูกซ่อน Expression Manager จะคืนค่าเป็นสตริงว่าง
หากไม่ใช้ NAOK: เมื่อมีคำถามหรือคำถามย่อยใดถูกซ่อน Expression Manager จะคืนค่าเป็นสตริงว่างเสมอ ซึ่งเทียบเท่ากับการคืนค่าเป็นเท็จ
.shown ใช้ระบบ NAOK เสมอ (เป็นสตริงว่างหากถูกซ่อน) แต่หากคุณต้องการรหัสของคำตอบ ควรเพิ่ม .NAOK ต่อท้ายรหัสคำถามเสมอ ยกเว้นในกรณีที่คุณต้องการเช่นนั้นและเข้าใจสิ่งที่ทำอยู่
ตัวอย่างและข้อมูลเพิ่มเติมอยู่ที่ Overriding Cascading Conditions
การเข้าถึงฟังก์ชัน
Expression Manager ให้การเข้าถึงฟังก์ชันทางคณิตศาสตร์ ฟังก์ชันสตริง และฟังก์ชันที่ผู้ใช้กำหนดเอง ดังที่แสดงด้านล่าง โดยมีฟังก์ชันเทียบเท่าใน PHP และ JavaScript เพื่อให้ทำงานได้เหมือนกันทั้งฝั่งเซิร์ฟเวอร์ (PHP) และฝั่งไคลเอนต์ (JavaScript) และสามารถเพิ่มฟังก์ชันใหม่ได้ง่าย
ฟังก์ชันที่มีให้ใช้งาน
ขณะนี้มีฟังก์ชันต่อไปนี้ให้ใช้งาน:
| ฟังก์ชัน | ความหมาย | ไวยากรณ์ |
|---|---|---|
| abs | ค่าสัมบูรณ์ | number abs(number) |
| acos | อาร์กโคไซน์ | number acos(number) |
| addslashes | ใส่เครื่องหมายสแลชให้กับสตริง | string addslashes(string) |
| asin | อาร์กไซน์ | number asin(number) |
| atan | อาร์กแทนเจนต์ | number atan(number) |
| atan2 | อาร์กแทนเจนต์ของสองตัวแปร | number atan2(number, number) |
| ceil | ปัดเศษขึ้น | number ceil(number) |
| checkdate | ส่งคืนค่า true(1) หากเป็นวันที่ที่ถูกต้องตามปฏิทินเกรกอเรียน | bool checkdate(month,day,year) |
| convert_value | แปลงค่าตัวเลขโดยใช้ตารางอินพุตและตารางเอาต์พุตของค่าตัวเลข | number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList) |
| cos | โคไซน์ | number cos(number) |
| count | นับจำนวนคำถามที่มีการตอบ (ไม่ว่างเปล่า) ในรายการ | number count(arg1, arg12, ..., argN) |
| countif | นับจำนวนคำถามที่มีการตอบในรายการที่เท่ากับอาร์กิวเมนต์แรก | number countif(matches, arg1, arg2, ... argN) |
| countifop | นับจำนวนคำถามที่มีการตอบในรายการที่ผ่านเกณฑ์ (arg op value) | number countifop(op, value, arg1, arg2, ... argN) |
| date | รูปแบบ วันที่/เวลาท้องถิ่น | string date(format [, timestamp=time()]) |
| exp | คำนวณเลขชี้กำลังของ e | number exp(number) |
| fixnum | แสดงตัวเลขโดยใช้เครื่องหมายจุลภาคเป็นตัวคั่นทศนิยม หากจำเป็น | string fixnum(number) |
| floor | ปัดเศษลง | number floor(number) |
| gmdate | รูปแบบวันที่แบบ GMT date/time | string gmdate(format [, timestamp=time()]) |
| html_entity_decode | แปลง HTML entity ทั้งหมดเป็นอักขระที่เกี่ยวข้อง (ใช้ ENT_QUOTES และ UTF-8 เสมอ) | string html_entity_decode(string) |
| htmlentities | แปลงอักขระที่เกี่ยวข้องทั้งหมดเป็น HTML entity (ใช้ ENT_QUOTES และ UTF-8 เสมอ) | string htmlentities(string) |
| expr_mgr_htmlspecialchars | แปลงอักขระพิเศษเป็น HTML entity (ใช้ ENT_QUOTES และ UTF-8 เสมอ) | string htmlspecialchars(string) |
| expr_mgr_htmlspecialchars_decode | แปลง HTML entity พิเศษกลับเป็นอักขระ (ใช้ ENT_QUOTES และ UTF-8 เสมอ) | string htmlspecialchars_decode(string) |
| idate | รูปแบบ เวลา/วันที่ท้องถิ่น เป็นจำนวนเต็ม | string idate(string [, timestamp=time()]) |
| if (Updated in 3.0.2 ) | if แบบ Excel (test,result_if_true[,result_if_false = ""]) | if(test,result_if_true[,result_if_false = ""]) |
| implode | เชื่อมค่าในอาร์เรย์ด้วยสตริง | string implode(glue,arg1,arg2,...,argN) |
| intval | รับค่าจำนวนเต็มของตัวแปร | int intval(number [, base=10]) |
| is_empty | ตรวจสอบว่าตัวแปรถือว่าว่างเปล่าหรือไม่ | bool is_empty(var) |
| is_float | ตรวจสอบว่าชนิดของตัวแปรเป็นเลขทศนิยมหรือไม่ | bool is_float(var) |
| is_int | ตรวจสอบว่าชนิดของตัวแปรเป็นจำนวนเต็มหรือไม่ | bool is_int(var) |
| is_nan | หาชนิดของตัวแปรที่ไม่ใช่ตัวเลข | bool is_nan(var) |
| is_null | หาตัวแปรที่เป็น NULL | bool is_null(var) |
| is_numeric | ตรวจสอบว่าตัวแปรเป็นตัวเลขหรือสตริงที่เป็นตัวเลขหรือไม่ | bool is_numeric(var) |
| is_string | ตรวจสอบว่าชนิดของตัวแปรเป็นสตริงหรือไม่ | bool is_string(var) |
| join (New in 2.0 build 130129) | เชื่อมองค์ประกอบเป็นสตริงใหม่ | join(arg1, arg2, ... argN) |
| list | ส่งคืนรายการค่าที่ไม่ว่างเปล่าโดยคั่นด้วยเครื่องหมายจุลภาค | string list(arg1, arg2, ... argN) |
| listifop (New in 3.16.1 ) | ส่งคืนรายการที่คั่นด้วย 'glue' ของคุณสมบัติคำถามที่ระบุ (retProp) จากคำถามในรายการที่ผ่านเกณฑ์ (cmpProp op value) | string listifop(cmpProp, op, value, retProp, glue, sgqa1, sgqa2, ... sgqaN) |
| log | ลอการิทึมของตัวเลขที่มีฐานตามที่กำหนด หรือลอการิทึมธรรมชาติ | number log(number,base=e) |
| ltrim | ตัดช่องว่าง (หรืออักขระอื่น) ออกจากจุดเริ่มต้นของสตริง | string ltrim(string [, charlist]) |
| max | หาค่าสูงสุด | number max(arg1, arg2, ... argN) |
| min | หาค่าต่ำสุด | number min(arg1, arg2, ... argN) |
| mktime | รับค่า UNIX timestamp ของวันที่ (อาร์กิวเมนต์ทั้ง 6 ตัวเป็นตัวเลือก) | number mktime([hour [, minute [, second [, month [, day [, year ]]]]]]) |
| modulo-function | ฟังก์ชันโมดูโลยังไม่รองรับ คุณสามารถใช้ฟังก์ชัน floor() แทนได้ | floor(x/y)==(x/y) |
| nl2br | แทรกการขึ้นบรรทัดใหม่ของ HTML ก่อนอักขระขึ้นบรรทัดใหม่ทั้งหมดในสตริง | string nl2br(string) |
| number_format | รูปแบบตัวเลขโดยมีการจัดกลุ่มหลักพัน | string number_format(number) |
| pi | รับค่าของ pi | number pi() |
| pow | นิพจน์เอ็กซ์โปเนนเชียล | number pow(base, exp) |
| quoted_printable_decode | แปลงสตริงแบบ quoted-printable เป็นสตริง 8 บิต | string quoted_printable_decode(string) |
| quoted_printable_encode | แปลงสตริง 8 บิตเป็นสตริงแบบ quoted-printable | string quoted_printable_encode(string) |
| quotemeta | อ้างอักขระเมตา | string quotemeta(string) |
| rand | สร้างเลขสุ่ม ดูตัวอย่างนี้ | int rand() OR int rand(min, max) |
| regexMatch | เปรียบเทียบสตริงกับนิพจน์ปรกติ | bool regexMatch(pattern,input) |
| round | ปัดเศษตัวเลขเป็นความแม่นยำเสริม | number round(val [, precision]) |
| rtrim | ตัดช่องว่าง (หรืออักขระอื่น) ออกจากท้ายสตริง | string rtrim(string [, charlist]) |
| sin | ไซน์ | number sin(arg) |
| sprintf | ส่งคืนสตริงที่จัดรูปแบบ | string sprintf(format, arg1, arg2, ... argN) |
| sqrt | รากที่สอง | number sqrt(arg) |
| stddev | คำนวณค่าเบี่ยงเบนมาตรฐานของกลุ่มตัวอย่างสำหรับรายการตัวเลข | number stddev(arg1, arg2, ... argN) |
| str_pad | เติมสตริงให้ได้ความยาวที่กำหนดด้วยสตริงอื่น | string str_pad(input, pad_length [, pad_string]) |
| str_repeat | ซ้ำค่าอักขระ | string str_repeat(input, multiplier) |
| str_replace | แทนที่สตริงที่ค้นหาทุกรายการด้วยสตริงทดแทน | string str_replace(search, replace, subject) |
| strcasecmp | การเปรียบเทียบสตริงที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ที่ปลอดภัยแบบไบนารี | int strcasecmp(str1, str2) |
| strcmp | การเปรียบเทียบสตริงที่ปลอดภัยแบบไบนารี | int strcmp(str1, str2) |
| strip_tags | แยก TAG HTML และ PHP ออกจากข้อความ | string strip_tags(str, allowable_tags) |
| stripos | ค้นหาตำแหน่งการเกิดขึ้นครั้งแรกของสตริงยูนิโค้ดโดยไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ (เริ่มจาก 0 ส่งคืน false หากไม่พบ) | int stripos(haystack, needle [, offset=0]) |
| stripslashes | ยกเลิกเครื่องหมายคำพูดจากข้อความที่มีเครื่องหมายคำพูด | string stripslashes(string) |
| stristr | strstr .ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ | string stristr(haystack, needle [, before_needle=false]) |
| strlen | รับค่าความยาวอักขระ | int strlen(string) |
| strpos | ค้นหาตำแหน่งการเกิดขึ้นครั้งแรกของสตริงยูนิโค้ด (เริ่มจาก 0 ส่งคืน false หากไม่พบ) | int strpos(haystack, needle [ offset=0]) |
| strrev | กลับค่าอักขระ | string strrev(string) |
| strstr | ค้นหาการเกิดขึ้นครั้งแรกของสตริง | string strstr(haystack, needle[, before_needle=false]) |
| strtolower | แปลงสตริงเป็นตัวพิมพ์เล็ก | string strtolower(string) |
| strtotime | แปลงคำอธิบายวันที่และเวลาเป็นข้อความภาษาอังกฤษให้เป็น Unix timestamp | int strtotime(string) |
| strtoupper | แปลงสตริงเป็นตัวพิมพ์ใหญ่ | string strtoupper(string) |
| substr | ส่งคืนบางส่วนของสตริงยูนิโค้ด | string substr(string, start [, length]) |
| sum | คำนวณผลรวมของค่าในอาร์เรย์ | number sum(arg1, arg2, ... argN) |
| sumifop | หาผลรวมของค่าของคำถามที่มีการตอบในรายการที่ผ่านเกณฑ์ (arg op value) | number sumifop(op, value, arg1, arg2, ... argN) |
| tan | แทนเจนต์ | number tan(arg) |
| time | ส่งค่าปัจจุบันของประทับเวลาU NIX | number time() |
| trim | ตัดช่องว่าง (หรืออักขระอื่น) ออกจากต้นและท้ายสตริง | string trim(string [, charlist]) |
| ucwords | แปลงอักขระตัวแรกของแต่ละคำในสตริงให้เป็นตัวพิมพ์ใหญ่ | string ucwords(string) |
| unique | ตอบกลับเป็นค่า จริง ถ้าการตอบคำถามที่ไม่ว่างเปล่าทั้งหมดไม่ซ้ำกัน | boolean unique(arg1, ..., argN) |
ฟังก์ชันที่วางแผนไว้หรืออยู่ระหว่างการพิจารณา
ฟังก์ชันอื่นๆ ที่วางแผนไว้ (หรืออยู่ระหว่างการพิจารณา) แต่ยังไม่ได้พัฒนา มีดังต่อไปนี้ บางฟังก์ชันมีไว้เพื่อความเข้ากันได้กับเครื่องมือแบบสำรวจอื่น
| ไวยากรณ์ | ความหมาย | หมายเหตุ |
|---|---|---|
| e() | คืนค่า e | |
| formatDate(X,PAT) | คืนค่าสตริงของวันที่ X ที่จัดรูปแบบตามรูปแบบวันที่ PAT ของ Java | |
| formatNumber(X,PAT) | คืนค่าสตริงของตัวเลข X ที่จัดรูปแบบตามรูปแบบตัวเลข PAT ของ Java | |
| getAnsOption(X) | Core plugin ExpressionAnswerOptions | |
| getAnsOption(X,Y) | Core plugin ExpressionAnswerOptions | |
| getRelevance(X) | คืนค่าสมการความสัมพันธ์กันของคำถาม X | |
| getStartTime() | คืนค่าวันที่ที่ตรงกับเวลาของระบบเมื่อเริ่มการสัมภาษณ์ | |
| getType(X) | คืนค่าชื่อชนิดข้อมูลในรูปแบบสตริง เช่น *NA* หาก isNA() | |
| gotoFirst() | ข้ามไปยังชุดคำถามแรกที่เกี่ยวข้อง - ซึ่งขัดกับลำดับการทำงานปกติของระบบ | |
| gotoNext() | ข้ามไปยังชุดคำถามที่เกี่ยวข้องชุดถัดไป - ซึ่งขัดกับลำดับการทำงานปกติของระบบ | |
| gotoPrevious() | ข้ามไปยังชุดคำถามที่เกี่ยวข้องชุดก่อนหน้า - ซึ่งขัดกับลำดับการทำงานปกติของระบบ | |
| isAsked(X) | คืนค่า true หากคำตอบไม่ใช่ *NA*, *INVALID* หรือ *UNASKED* | |
| isInvalid(X) | คืนค่า true หากคำตอบเป็นชนิด *INVALID* | |
| isNA(X) | คืนค่า true หากคำตอบเป็นชนิด *NA* | |
| isNotUnderstood(X) | คืนค่า true หากคำตอบเป็นชนิด *HUH* | |
| isRefused(X) | คืนค่า true หากคำตอบเป็นชนิด *REFUSED* | |
| isSpecial(X) | คืนค่า true หากคำตอบเป็นชนิด *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN* หรือ *HUH* | |
| isUnknown(X) | คืนค่า true หากคำตอบเป็นชนิด *UNKNOWN* | |
| jumpTo(X) | ข้ามไปยังกลุ่มที่มีคำถามตามชื่อที่ระบุ -- ซึ่งขัดกับลำดับการทำงานปกติของระบบ | |
| jumpToFirstUnasked() | ข้ามไปยังคำถามแรกที่ยังไม่ถูกถาม |
|
| lastIndexOf(X,Y) | คืนค่าดัชนีสุดท้าย (เริ่มจาก 0) ของสตริง Y ในสตริง X และคืนค่า -1 หาก X ไม่มี Y อยู่ | |
| list(X,...) | สตริงที่ประกอบด้วยรายการค่าบวกที่คั่นด้วยเครื่องหมายจุลภาค โดยใช้คำว่า "และ" คั่นสองค่าสุดท้าย | |
| mean(X,...) | คืนค่าเฉลี่ยของรายการค่า | |
| numAnsOptions(X) | คืนค่าจำนวนตัวเลือกของคำตอบที่คำถาม X มี | |
| orlist(X,...) | สตริงที่ประกอบด้วยรายการค่าบวกที่คั่นด้วยเครื่องหมายจุลภาค โดยใช้คำว่า "หรือ" คั่นสองค่าสุดท้าย | |
| parseDate(X,PAT) | คืนค่าวันที่ของสตริง X ที่แปลงตามรูปแบบวันที่ PAT ของ Java | |
| parseNumber(X,PAT) | คืนค่าตัวเลขของสตริง X ที่แปลงตามรูปแบบตัวเลข PAT ของ Java | |
| showAllResponsesExcept( questionList,attributeList,attributeTitleList) | questionList = รายการตัวระบุคำถามที่คั่นด้วยเครื่องหมาย pipe; attributeList = รายการคุณสมบัติที่คั่นด้วยเครื่องหมาย pipe (เช่น question#, title, text, type - เพื่อให้คุณเลือกได้ว่าจะแสดงอะไร); attributeTitleList = รายการหัวตารางที่คั่นด้วยเครื่องหมาย pipe เพื่อให้สร้างรายงานหลายภาษาได้ | |
| showTheseResponses( questionList,attributeList,attributeTitleList) | questionList = รายการตัวระบุคำถามที่คั่นด้วยเครื่องหมาย pipe; attributeList = รายการคุณสมบัติที่คั่นด้วยเครื่องหมาย pipe (เช่น question#, title, text, type - เพื่อให้คุณเลือกได้ว่าจะแสดงอะไร); attributeTitleList = รายการหัวตารางที่คั่นด้วยเครื่องหมาย pipe เพื่อให้สร้างรายงานหลายภาษาได้ |
Expression Manager รู้ว่าตัวแปรใดเป็นตัวแปรภายในหน้า
เพื่อสร้าง JavaScript ของหน้าได้อย่างถูกต้อง Expression Manager จำเป็นต้องรู้ว่าตัวแปรใดถูกกำหนดค่าอยู่ในหน้านั้น และ JavaScript ID ของตัวแปรเหล่านั้นคืออะไร (เช่น สำหรับ document.getElementById(x)) นอกจากนี้ยังต้องรู้ว่าตัวแปรใดถูกกำหนดค่าอยู่ในหน้าอื่น (เพื่อให้แน่ใจว่ามีฟิลด์ <input type='hidden' value='x'> ที่จำเป็นและมีค่าครบถ้วน)
เงื่อนไขแบบต่อเนื่อง (Cascading Conditions)
หากตัวแปรใดตัวแปรหนึ่งไม่เกี่ยวข้อง สมการทั้งหมดจะไม่เกี่ยวข้อง (เป็น false) ตัวอย่างเช่น ในตารางต่อไปนี้ N/A หมายความว่าตัวแปรตัวใดตัวหนึ่งไม่เกี่ยวข้อง
| ตัวดำเนินการ | ตัวอย่าง | a | b | ผลลัพธ์ |
|---|---|---|---|---|
| + (unary) | +a | N/A | false | |
| ! | !a | N/A | false | |
| == (or eq) | a == b | N/A | 5 | false |
| == (or eq) | a == b | N/A | 0 | false |
| == (or eq) | a == b | N/A | N/A | false |
| != (or ne) | a != b | N/A | 5 | false |
| != (or ne) | a != b | N/A | N/A | false |
| != (or ne) | a != b | N/A | 0 | false |
| > (or gt) | a > b | N/A | 5 | false |
| >= (or ge) | a >= b | N/A | 5 | false |
| < (or lt) | a < b | N/A | 5 | false |
| <= (or le) | a <= b | N/A | 5 | false |
| and | a and b | N/A | 5 | false |
| and | a and b | N/A | N/A | false |
| or | a or b | N/A | N/A | false |
| or | a or b | N/A | 5 | false |
| + | a + b | N/A | 5 | false |
| * | a * b | N/A | 5 | false |
| / | a / b | 5 | N/A | false |
| () | (a) | N/A | false | |
| (exp) | (a && b) | N/A | 5 | false |
| (exp) op (exp) | (b + b) > (a && b) | N/A | 5 | false |
| function | sum(a,b,b) | N/A | 5 | false |
| function | max(a,b) | N/A | 5 | false |
| function | min(a,b) | N/A | 5 | false |
| function | implode(', ',a,b,a,b) | N/A | 5 | false |
| function | if(a,a,b) | N/A | 5 | false |
| function | is_empty(a) | N/A | false | |
| function | is_empty(a) | 0 (or blank) | true | |
| function | !is_empty(a) | N/A | false |
การแทนที่เงื่อนไขแบบต่อเนื่อง (Overriding Cascading Conditions)
สมมติว่าคุณต้องการแสดงผลรวมสะสมของคำตอบที่เกี่ยวข้องทั้งหมด คุณอาจลองใช้สมการ {sum(q1,q2,q3,...,qN)} อย่างไรก็ตาม ระบบจะแปลงสมการนี้ภายในเป็น LEMif(LEManyNA('q1','q2','q3',...,'qN'),,sum(LEMval('q1'),LEMval('q2'),LEMval('q3'),...,LEMval('qN'))) ดังนั้นหากค่า q1-qN ตัวใดตัวหนึ่งไม่เกี่ยวข้อง สมการจะคืนค่า false เสมอ ในกรณีนี้ sum() จะแสดง 0 จนกว่าจะตอบครบทุกคำถาม
เพื่อหลีกเลี่ยงปัญหานี้ คุณสามารถเพิ่มคำต่อท้าย ".NAOK" ให้กับตัวแปรแต่ละตัว (หมายถึง Not Applicable is OK) ซึ่งจะทำให้เกิดพฤติกรรมดังต่อไปนี้ สมมติว่าคุณมีตัวแปร q1.NAOK
- q1 จะไม่ถูกเพิ่มลงในส่วน LEManyNA()
- LEMval('q1') จะยังคงตรวจสอบว่าการตอบคำถามเกี่ยวข้องหรือไม่ และจะคืนค่า '' หากไม่เกี่ยวข้อง (ดังนั้นการตอบคำถามที่ไม่เกี่ยวข้องแต่ละรายการจะถูกละเว้น แต่จะไม่ทำให้นิพจน์ทั้งหมดเป็นโมฆะ)
ดังนั้นวิธีแก้ปัญหาผลรวมสะสมคือใช้สมการ sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK)
การใช้คำต่อท้าย .NAOK ยังช่วยให้ผู้สร้างออกแบบแบบสำรวจที่มีหลายเส้นทางที่เป็นไปได้ แต่ไปบรรจบกันที่เส้นทางร่วมในภายหลังได้ ตัวอย่างเช่น สมมติว่าผู้ตอบตอบแบบสำรวจในลักษณะที่อยู่นอกช่วงปกติของการตอบคำถาม ผู้สร้างสามารถแจ้งเตือนผู้ตอบว่าอาจไม่ได้ผลลัพธ์ที่ถูกต้อง และถามว่าต้องการทำแบบสำรวจต่อหรือไม่ หากตอบว่าใช่ คำถามที่เหลือจะถูกแสดง เงื่อนไขสำหรับ "คำถามที่เหลือ" จะตรวจสอบว่าการตอบคำถามเบื้องต้นอยู่ในช่วงปกติ หรือ ผู้ตอบตอบว่าใช่สำหรับคำถามที่เกี่ยวข้องเฉพาะเมื่อตอบนอกช่วงปกติ
Expression Manager รองรับ Conditional Micro-Tailoring อย่างไร?
ต่อไปนี้เป็นตัวอย่างของ micro-tailoring (โดย Question Type=='expr' หมายถึงสมการ):
| รหัสคำถาม | ความสัมพันธ์กัน | ชนิดของคำถาม | คำถาม |
|---|---|---|---|
| name | 1 | text | What is your name? |
| age | 1 | text | How old are you? |
| badage | !is_empty(age) | expr | {(age<16) or (age>80)} |
| agestop | badage | message | Sorry, {name}, you are too {if( (age<16),'young',if( (age>80),'old','middle-aged') ) } for this test. |
| kids | !badage | yesno | Do you have children? |
| parents | 1 | expr | {!badage && kids=='Y'} |
| numKids | parents | text | How many children do you have? |
| kid1 | parents && numKids >= 1 | text | How old is your first child? |
| kid2 | parents && numKids >= 2 | text | How old is your second child? |
| kid3 | parents && numKids >= 3 | text | How old is your third child? |
| kid4 | parents && numKids >= 4 | text | How old is your fourth child? |
| kid5 | parents && numKids >= 5 | text | How old is your fifth child? |
| sumage | 1 | expr | {sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)} |
| report | parents | yesno | {name}, you said you are {age} and that you have {numKids}. The sum of ages of your first {min(numKids,5)} kids is {sumage} |
คำถามทั้งหมดนี้สามารถอยู่ในหน้าเดียวกันได้ (เช่น ในกลุ่มเดียวกัน) และจะแสดงเฉพาะคำถามที่เกี่ยวข้องเท่านั้น นอกจากนี้ เมื่อคุณป้อนอายุของเด็ก นิพจน์ sum() ในคำถามสุดท้ายจะอัปเดตบนหน้าแบบไดนามิก
Expression Manager ทำงานนี้โดยครอบแต่ละนิพจน์ด้วยองค์ประกอบ <span> ที่มีชื่อกำกับ ทุกครั้งที่ค่ามีการเปลี่ยนแปลง ระบบจะคำนวณนิพจน์ที่ควรปรากฏในองค์ประกอบ <span> นั้นใหม่ และสร้างการแสดงผลขึ้นใหม่ คุณสามารถมีนิพจน์ที่ปรับแต่งเช่นนี้ได้หลายสิบหรือหลายร้อยรายการในหน้าเดียวกัน และหน้าจะแสดงผลทั้งหมดใหม่ในการรีเฟรชหน้าจอครั้งเดียว
การเปรียบเทียบฟีเจอร์ของ LimeSurvey 1.91+ กับฟังก์ชันของ Expression Manager
| ฟีเจอร์เดิม | ฟีเจอร์ใหม่ | หมายเหตุ |
|---|---|---|
| เงื่อนไข | ความสัมพันธ์กัน | คุณสามารถใช้สมการเงื่อนไขที่ซับซ้อนมากได้ และเข้าถึงตัวแปรได้หลากหลายยิ่งขึ้น |
| การประเมิน | สมการ | คะแนนการประเมินใดๆ สามารถจัดโครงสร้างใหม่เป็นสมการได้ ซึ่งช่วยให้มั่นใจว่าคะแนนถูกบันทึกลงในฐานข้อมูล และยังช่วยให้คุณเห็นการเปลี่ยนแปลงของคะแนนแบบไดนามิกบนหน้าปัจจุบัน |
| Replacements | Expression Manager | เอนจินหลักจะรับสตริงอินพุตและถือว่าทุกอย่างภายในเครื่องหมายปีกกาเป็นนิพจน์ - จึงรองรับการแทนที่ทุกประเภทในอดีต เพื่อไม่ให้ JavaScript ที่ฝังอยู่เสียหาย Expression Manager จะประมวลผลเนื้อหาระหว่างเครื่องหมายปีกกาเฉพาะเมื่อ (a) ไม่มีช่องว่างนำหน้าหรือตามหลังภายในเครื่องหมายปีกกา - เช่น {expr} เป็นนิพจน์ แต่ { expr}, {expr } และ { expr } ไม่ใช่นิพจน์ นอกจากนี้ Expression Manager จะไม่ประมวลผลเนื้อหาภายในสตริงของตัวเอง (เช่น {list('hi','there {braces}')} จะสร้างผลลัพธ์ "hi there {braces}") และจะละเว้นเครื่องหมายปีกกาที่ใช้ escape ด้วย (เช่น \{this is not an expression\}) |
| การตรวจสอบ | Expression Manager | แผนคือการนำคุณสมบัติคำถามค่าต่ำสุด/สูงสุดในปัจจุบันมาให้ Expression Manager ประมวลผล ด้วยวิธีนี้ค่าต่ำสุด/สูงสุดจึงสามารถเป็นนิพจน์ได้เอง |
การไฮไลต์ไวยากรณ์ (Syntax Highlighting)
เพื่อช่วยในการป้อนและตรวจสอบนิพจน์ EM มีการไฮไลต์ไวยากรณ์พร้อมคุณลักษณะต่อไปนี้:
ประเภทและความหมายของการไฮไลต์ไวยากรณ์
| สี | ตัวอย่าง | ความหมาย | ทูลทิป | หมายเหตุ |
|---|---|---|---|---|
| พื้นหลังสีแทน | Sample | สมการทั้งหมด | ไม่มี | ทุกอย่างภายในวงเล็บปีกกาที่ระบบรู้จักว่าเป็นสมการ (เช่น ไม่มีช่องว่างนำหน้าหรือตามหลัง) จะถูกแสดงด้วยพื้นหลังสีแทน เพื่อให้แยกออกจากข้อความโดยรอบได้ง่ายขึ้น |
| ตัวอักษรสีแดงตัวหนา | Sample | ข้อผิดพลาด | คำอธิบายข้อผิดพลาด | อาจเป็นตัวแปรที่ไม่รู้จักหรือข้อผิดพลาดในฟังก์ชัน เป็นต้น แบบสำรวจอาจใช้งานไม่ได้เลย โดยข้อผิดพลาดนี้จะไม่แสดงให้ผู้ใช้สาธารณะเห็น |
| ตัวอักษรสีน้ำเงิน | Sample | ชื่อฟังก์ชัน | ความหมายและไวยากรณ์ที่ใช้ได้ | ชื่อฟังก์ชัน หรือสิ่งที่ควรเป็นฟังก์ชันเนื่องจากตามด้วยวงเล็บเปิด จะแสดงด้วยตัวอักษรสีน้ำเงินตัวหนา ทูลทิปจะแสดงความหมายและไวยากรณ์ที่ใช้ได้ของฟังก์ชัน |
| ตัวอักษรสีเทา | Sample | สตริง | ไม่มี | สตริงที่อยู่ในเครื่องหมายอัญประกาศเดี่ยวและคู่จะแสดงด้วยตัวอักษรสีเทา |
| ตัวอักษรสีฟ้าอมเขียว | Sample | ตัวแปรที่ถูกกำหนดค่าในหน้าเดียวกัน | [ชื่อหรือรหัส SGQA]: คำถาม; ค่า; answerList แสดงรหัสของแต่ละค่า | ตัวแปรใดก็ตามที่ถูกกำหนดค่าในหน้าเดียวกับคำถามปัจจุบันจะแสดงด้วยตัวอักษรสีฟ้าอมเขียว ซึ่งแสดงว่าสามารถอัปเดตได้ใน JavaScript ทูลทิปจะแสดงชื่อ คำถามจริง และค่าปัจจุบัน (หรือว่างหากยังไม่ได้กำหนด) หากประเภทคำถามคาดหวังคำตอบจากชุดค่าที่กำหนดไว้ จะแสดงการจับคู่ระหว่างรหัสกับค่าที่แสดง |
| ตัวอักษรสีเขียว | Sample | ตัวแปรที่ถูกกำหนดค่าในหน้าก่อนหน้า | [ชื่อหรือรหัส SGQA]: คำถาม; ค่า; answerList แสดงรหัสของแต่ละค่า | ตัวแปรใดก็ตามที่ถูกกำหนดค่าในหน้าก่อนหน้าจะแสดงด้วยตัวอักษรสีเขียวตัวหนา ทูลทิปจะแสดงชื่อ คำถามจริง และค่าปัจจุบัน (หรือว่างหากยังไม่ได้กำหนด) หากประเภทคำถามคาดหวังคำตอบจากชุดค่าที่กำหนดไว้ จะแสดงการจับคู่ระหว่างรหัสกับค่าที่แสดง |
| ตัวอักษรสีชมพูตัวหนา | Sample | ตัวแปรที่ถูกกำหนดค่าในหน้าถัดไป โดยทั่วไป: ว่างเมื่อเริ่มแบบสำรวจ แต่อาจมีค่าได้จากการใช้ดัชนีหรือการย้อนกลับ | [ชื่อหรือรหัส SGQA]: คำถาม; ค่า; answerList แสดงรหัสของแต่ละค่า | ตัวแปรใดก็ตามที่ถูกกำหนดค่าในหน้าถัดไปจะแสดงด้วยตัวอักษรสีชมพูตัวหนา ทูลทิปจะแสดงชื่อ คำถามจริง และค่าปัจจุบัน (หรือว่างหากยังไม่ได้กำหนด) หากประเภทคำถามคาดหวังคำตอบจากชุดค่าที่กำหนดไว้ จะแสดงการจับคู่ระหว่างรหัสกับค่าที่แสดง |
| ตัวอักษรสีแทนตัวหนา | Sample | ค่าแทนที่ของ Lime | ค่า | สตริงแทนที่ของ Lime (เช่น {TOKEN:xxx}, {PRIVACY_MESSAGE}) จะแสดงด้วยตัวอักษรสีแทนตัวหนา |
| ตัวอักษรสีแดง | Sample | ตัวดำเนินการกำหนดค่า (=) | ข้อความเตือน | หากคุณใช้ตัวดำเนินการกำหนดค่า (=) ตัวดำเนินการนั้นจะแสดงด้วยตัวอักษรสีแดง เพื่อช่วยป้องกันการกำหนดค่าซ้ำโดยไม่ตั้งใจ ในกรณีที่คุณต้องการตรวจสอบว่า a == b แต่กลับเป็นการตั้งค่า a = b |
| ตัวอักษรสีดำปกติ | Sample | เครื่องหมายวรรคตอน | ไม่มี | เครื่องหมายวรรคตอนอื่นๆ ทั้งหมดภายในนิพจน์จะแสดงด้วยตัวอักษรสีดำปกติ |
| ตัวอักษรในกรอบสีแดง | เส้นสีแดงตัวหนาล้อมรอบข้อผิดพลาด | ข้อผิดพลาดทางไวยากรณ์ | คำอธิบายข้อผิดพลาด | ข้อผิดพลาดทางไวยากรณ์ที่ตรวจพบจะแสดงโดยมีกรอบสีแดงล้อมรอบ ทูลทิปจะแสดงข้อผิดพลาดนั้น ตัวอย่างเช่น วงเล็บที่ไม่ตรงกัน การใช้ฟังก์ชันที่ไม่มีอยู่ การส่งจำนวนอาร์กิวเมนต์ให้ฟังก์ชันไม่ถูกต้อง นิพจน์ที่โครงสร้างไม่ดี (เช่น ไม่มีตัวดำเนินการระหว่างตัวแปร) การพยายามกำหนดค่าใหม่ให้ตัวแปรแบบอ่านอย่างเดียว การพยายามกำหนดค่าให้สิ่งที่ไม่ใช่ตัวแปร หรือการใช้ไวยากรณ์ที่ไม่รองรับ โปรดทราบว่าระบบตรวจจับข้อผิดพลาดทางไวยากรณ์อาจรายงานเพียงข้อผิดพลาดเดียวในนิพจน์ แม้จะมีข้อผิดพลาดหลายจุด อย่างไรก็ตาม หากตรวจพบข้อผิดพลาด จะมีการแสดงอย่างน้อยหนึ่งรายการ |
บทความที่เกี่ยวข้อง
แบบสำรวจตัวอย่างของ Expression Manager
กรณีการใช้งานและวิธีการ
ตัวอย่างทีละขั้นตอน
ฟังก์ชันสถิติของ Expression Manager
เอกสารอ้างอิงสำหรับนักพัฒนา










