Expression Manager
From LimeSurvey Manual
Snabbstartsguide
Översikt
När du anpassar dina enkäter behöver du vanligtvis ett sätt att ange följande:
- Navigering/Förgrening - låta en deltagares svar ändra i vilken ordning frågorna ställs
- Anpassning/Piping - hur frågan ska formuleras (till exempel genom att hänvisa till tidigare svar eller böja meningar utifrån antalet eller könet på dina deltagare), eller hur du skapar anpassade rapporter (som utvärderingspoäng eller skräddarsydda råd).
- Validering - säkerställa att svaren uppfyller vissa kriterier, som minsta och högsta värden, eller matchar ett inmatningsmönster
Expression Manager (EM) erbjuder ett intuitivt sätt att ange logiken för var och en av dessa funktioner. Nästan allt som du kan skriva som en vanlig matematisk ekvation är ett giltigt uttryck, även om du anropar funktioner. EM ger för närvarande tillgång till 80 funktioner och kan enkelt utökas med fler. Du kan också komma åt dina variabler med läsbara variabelnamn (i stället för SGQA-namn).
Följande avsnitt visar de viktigaste ställena där Expression Manager används
Vissa enkäter använder "Goto-logik", där du till exempel hoppar till fråga 5 om du svarar på fråga 1 med alternativ C. Det här tillvägagångssättet är mycket begränsande, eftersom det är svårt att validera och lätt går sönder när du måste ändra ordning på frågorna. EM använder en boolesk relevansekvation för att ange alla villkor under vilka en fråga kan vara giltig. Om frågan är relevant visas den, annars är den Ej tillämplig och värdet NULL lagras i databasen. Detta liknar det som kan göras med villkorseditorn, men med EM kan du enkelt ange mycket mer komplexa och kraftfulla kriterier (och använda variabelnamnet i stället för SGQA-namn).
Den här bilden visar ett sätt att granska relevanslogiken för en enkät. Den beräknar kroppsmasseindex (BMI). Relevansekvationen visas inom hakparentes direkt efter variabelnamnet (som är grönt). Relevansen för weight, weight_units, height och height_units är alltså alla 1, vilket betyder att de frågorna alltid ställs. Relevansen för BMI är dock {!is_empty(height) and !is_empty(weight)}, vilket betyder att BMI bara beräknas om deltagaren anger ett värde för både height och weight (så att risken för division med noll undviks). Frågan Report visas dessutom bara om deltagaren svarar på alla fyra huvudfrågorna (height, height_units, weight, weight_units).
Relevans visas och kan redigeras på följande ställen:
Visa / redigera relevans på frågenivå
Den här ekvationen beräknar kroppsmasseindex (BMI). Frågan ställs bara om personen först anger sin längd och vikt.
Det här är redigeringsskärmen för BMI-frågan.
Observera att du inte använder klammerparenteser när du anger en relevansekvation.
Visa / redigera relevans på gruppnivå
Det här är en exempelenkät för folkräkning. Den första sidan frågar hur många personer som bor med dig och lagrar det i variabeln "cohabs". Sidan visas bara om du har fler än en person i hushållet (så den visas för den andra personen som bor med dig) och visas dessutom bara om du har angett hur person ett är släkt med dig (p1_rel).
Som du ser har gruppen också relevanskriterier på frågenivå, så att varje fråga bara visas när du har svarat på frågan före den (t.ex. {!is_empty(p1_sex)}). EM kombinerar relevansen på grupp- och frågenivå åt dig. Frågor i en grupp ställs bara om gruppen som helhet är relevant. Därefter ställs bara den delmängd av frågorna i gruppen som är relevanta.
Här är skärmen för att redigera relevansen på gruppnivå för den frågan:
Observera att du inte använder klammerparenteser när du anger en relevansekvation.
Anpassning/Piping
Med EM kan du enkelt göra enkel och komplex villkorsstyrd anpassning av dina frågor. Ibland behöver du bara enkel ersättning, som att säga "Du sa att du köpte [Produkt]. Vad gillade du bäst med den?". Ibland behöver du villkorsstyrd ersättning som "[Herr/Fru] [Efternamn], skulle du vilja besvara vår enkät?". I det här fallet vill du använda Herr eller Fru utifrån personens kön. Andra gånger behöver du ännu mer komplex ersättning (till exempel baserad på en matematisk beräkning). EM stöder alla dessa typer av anpassning/piping.
Villkorsstyrda ekvationer
Exemplet med kroppsmasseindex visar hur man kan beräkna en persons BMI, samtidigt som personen får ange sin längd och vikt i metriska eller icke-metriska enheter.
Här är weight_kg {if(weight_units == 'kg', weight, weight * .453592)}. Funktionen if() innebär att om deltagaren angav vikten i kilogram används det värdet, annars multipliceras det angivna värdet (som var i pund) med .453592 för att omvandla det till kilogram. Variabeln height_m använder en liknande metod för att beräkna personens längd i meter, även om längden angavs i tum.
BMI beräknar viktformeln som {weight_kg / (height_m * height_m)}.
Slutligen anpassar rapporten meddelandet villkorligt för deltagaren och talar om vad som angavs. ("Du sa att du är 2 meter lång och väger 70 kg.")
Även om det inte syns tydligt i bilden ovan använder weight_status nästlade if()-satser för att kategorisera personen från undervikt till svår fetma. Du kan se dess ekvation i vyn Visa logik
I redigeringsfönstret för den här frågan kan du se två saker:
- Vid anpassning måste uttryck omges av klammerparenteser
- Uttryck kan sträcka sig över flera rader om du, som i det här fallet, vill göra den nästlade villkorslogiken lättare att läsa.
Anpassade frågor, svar och rapporter
Det här exemplet visar BMI-rapporten.
Här är redigeringsfönstret för samma fråga.
Som du ser behandlas allt inom klammerparenteser som ett uttryck och syntaxmarkeras därför (färgkodas) i den föregående bilden. Om du har några skrivfel (till exempel felstavade eller odefinierade variabelnamn eller funktioner) visar EM ett fel, som det här, där det framgår att height_unit är ett odefinierat variabelnamn (det ska vara height_units) och att rnd() är en odefinierad funktion (rätt funktionsnamn är round()). I båda fallen omges felen av en röd ruta så att de är lättare att upptäcka och åtgärda.
Du kan också se att du snabbt kan skapa komplexa rapporter, till exempel en tabell med angivna värden eller skräddarsydda råd.
Kom ihåg att vid all anpassning måste uttryck omges av klammerparenteser, så att LimeSurvey vet vilka delar av frågan som är fri text och vilka som ska tolkas av Expression Manager.
Validering
EM styr hur de flesta avancerade frågealternativ fungerar. Dessa styr bland annat min-/maxantal svar, min-/maxvärden för enskilda svar, min-/maxsummor och kontroll av att angivna värden matchar angivna strängmönster. Du anger dessa avancerade frågealternativ som vanligt. Nu betraktas dock alla värden i dessa fält som uttryck, så du kan ha min-/maxkriterier med komplexa villkorliga samband med andra frågor.
I alla dessa fall används inte klammerparenteser när du anger det, eftersom det avancerade frågealternativet alltid betraktas som ett uttryck.
Sidan Exempelenkäter visar många fungerande exempel på hur uttryck används för validering.
Introduktion
LimeSurvey använder den nya modulen Expression Manager (EM), som gör det möjligt för LimeSurvey att stödja mer komplex förgrening, bedömningar, validering och anpassning. Den ersätter hur LimeSurvey hanterar ersättningar, villkor och bedömningar i bakgrunden. Den ökar också bearbetningshastigheten avsevärt eftersom nästan alla databasläsningar under körning elimineras. EM utvecklades av Dr. Thomas White (TMSWhite).
Den här wikisidan är den slutgiltiga referensen för syntax och funktionalitet i Expression Manager.
Viktiga definitioner
- Uttryck: Allt som omges av klammerparenteser
- Så länge det inte finns något blanksteg direkt efter den inledande parentesen eller före den avslutande klammerparentesen
- Innehållet i uttryck utvärderas av EM, så de kan innehålla matematiska formler, funktioner samt komplex sträng- och datumhantering.
- Anpassning: Kallas ibland "piping", och är processen att villkorligt ändra text
- Du har tillgång till alla ersättningsfält, deltagardata och svarsdata.
- Du får också enklare åtkomst till frågor, svar och deras egenskaper.
- Relevansekvation: Ett nytt frågeattribut som styr om en fråga visas
- Om det finns en relevansekvation visas frågan bara om relevansen utvärderas till sant.
- Internt blir alla kommandon av typen array_filter och array_filter_exclude relevans på delfrågenivå
- Ekvationsfrågetyp: En ny frågetyp som sparar beräkningar eller rapporter i databasen
- Den är som en Boilerplate-fråga, men dess innehåll sparas i databasen även om du har valt "Dölj alltid denna fråga"
- Frågekod: Detta är det föredragna variabelnamnet för EM
- Det kan vara ett beskrivande namn som anger frågans syfte, vilket gör komplex logik lättare att läsa
- Giltiga frågekoder ska INTE börja med en siffra, så när du använder frågekoden för att numrera dina frågor kan du helt enkelt använda "q1", "q1a" eller "g1q2".
- Det är vad som för närvarande blir variabelnamnet om du exporterar data till SPSS eller R, så om du gör statistisk analys har du förmodligen redan gjort den unik.
Måste jag använda EM?
Det korta svaret är nej (men också ja).
EM är helt bakåtkompatibelt med befintliga enkäter. Så om du är nöjd med att använda villkor och bedömningar på det sätt som LimeSurvey gjorde i versioner <= 1.91+ kan du fortsätta med det.
EM ersätter dock helt hur LimeSurvey internt hanterar villkor. Du kan fortfarande använda villkorsredigeraren för att skapa och hantera villkor, men LimeSurvey 1.92 konverterar dem till motsvarande relevansekvationer. Som en del av uppgraderingen konverterar LimeSurvey 1.92 automatiskt alla befintliga villkor till relevansekvationer.
Detta bör ge dig det bästa av två världar - du kan fortsätta använda LimeSurvey som du är van vid, men ser den motsvarande relevansekvationen så att du gradvis kan gå över till att använda relevansekvationer direkt när du tycker det passar.
Kan jag blanda användning av villkor och relevans?
Ja. Du kan använda villkorseditorn för vissa frågor och relevansredigeraren för andra. Villkor konverteras automatiskt till relevans när du sparar frågan.
Observera att vi utgår från att du, om du använder villkorseditorn, vill att dessa villkor ska skriva över en manuellt inmatad relevansekvation. Om du har befintliga villkor och vill redigera relevansen manuellt bör du därför radera villkoren för frågan först. Kopiera närmare bestämt den genererade relevansekvationen till en textredigerare, använd villkorsmenyn för att radera alla villkor för frågan (vilket även raderar relevansen), redigera sedan frågan och klistra in den genererade relevansekvationen från textredigeraren i relevansfältet för frågan (och spara frågan). Om efterfrågan är tillräckligt stor på att kunna radera villkor utan att radera den genererade relevansekvationen kan vi lägga till en funktion för massomvandling.
Hur bör jag välja mellan villkor och relevans?
Här är en lista över för- och nackdelar med respektive stil:
| Stil | Fördelar | Nackdelar |
|---|---|---|
| Villkor | 1. Ett trevligt grafiskt gränssnitt för att skapa enkla villkor 2. Det grafiska gränssnittet är väldokumenterat och välkänt hos supportteamet |
1. Stöder bara enkla jämförelser och hanterar inte OCH/ELLER-villkor särskilt bra 2. Kaskadvillkor fungerar oregelbundet 3. Långsamt - databasintensivt, vilket kan göra långa enkäter långsammare 4. Vissa rapporterade problem med att läsa in villkor på nytt 5. Det grafiska gränssnittet skalar dåligt när det finns dussintals, hundratals eller tusentals frågor 6. Kan gå långsamt att konvertera pappersbaserade enkäter eftersom SGQA-namn måste användas 7. Kräver ofta en programmerare för att skriva den logik som behövs för komplex förgrening |
| Relevans | 1. Stöder mycket komplex logik, inklusive över 80 funktioner samt matematiska operatorer och strängoperatorer 2. Perfekt stöd för kaskadlogik 3. Snabbt - inga extra databasanrop, vilket gör att enkäter med över 1000 frågor stöds 4. Inga problem med att läsa in logik på nytt eftersom SGQA-koder inte behövs 5. Syntaxmarkeringen skalar till enkäter med över 1000 frågor 6. Enkelt och snabbt att använda för grupper som vill datorisera befintliga pappersbaserade enkäter. 7. Stöder enkelt halvstrukturerade intervjuer och epidemiologiska enkäter utan att man behöver programmerare |
1. Inget grafiskt gränssnitt för enkla villkor - använd syntaxmarkering i stället 2. Nytt, så supportteamen har ännu inte lärt sig EM fullt ut. |
Sammanfattningsvis: om du är nöjd med hur LimeSurvey 1.91+ fungerar finns det ingen anledning att ändra ditt arbetssätt.
Vilka andra fördelar finns det med att använda EM?
Här är några andra skäl till att du kanske vill använda EM.
- Beräkningar - du kan skapa vilken beräkning du kan tänka dig:
- Du har tillgång till alla vanliga matematiska operatorer och funktioner
- Du har tillgång till över 70 matematiska funktioner samt funktioner för datum- och strängbehandling
- Det är relativt enkelt för utvecklare att lägga till nya funktioner om användare behöver dem
- Lagra beräkningar i databasen
- Du kan nu beräkna enkla och komplexa beräkningar och/eller skalpoäng OCH få dem lagrade i databasen utan att behöva JavaScript.
- Du använder frågetypen Ekvation för att åstadkomma detta.
- Utvärderingar
- Du kan nu skapa utvärderingar eller skalpoäng från vilken frågetyp som helst, inte bara den delmängd som tidigare stöddes
- Du kan använda anpassning för att visa löpande eller totala utvärderingspoäng var som helst - även på samma sida
- Du har större kontroll över de rapporter som genereras utifrån dessa utvärderingspoäng
- Du kan lagra utvärderingspoäng i databasen utan att behöva JavaScript
- Du kan dölja utvärderingspoäng utan att behöva JavaScript eller CSS
- Ersättningsfält
- Använd frågekoden för att infoga värden från svar på föregående frågor - det gör det lättare att läsa och validera.
- Anpassning - du kan visa text villkorligt baserat på andra värden
- Använd lämplig titel för en person, till exempel (t.ex. "Hej [Hr/Fru] Smith")
- Skapa grammatiskt korrekta meningar när singular/plural spelar roll: (t.ex. "Du har 1 barn" jämfört med "Du har 2 barn")
- Böj verb och substantiv på lämpligt sätt utifrån ämnets kön och numerus.
- Nya variabelattribut - du har tillgång till följande för din anpassning:
- (inget suffix) - ett alias för qcode.code
- .code - den valda svarskoden för frågan om den är relevant (annars tom), eller textvärdet om det inte är en kodad fråga
- .NAOK - samma som .code, men kan ingå i beräkningar eller listor även om frågan är irrelevant
- .value - utvärderingsvärdet för frågan om den är relevant (annars tomt), eller textvärdet om det inte är en kodad fråga -- tillgängligt om utvärderingar är aktiverade för enkäten, annars alltid noll
- .valueNAOK - samma som .value, men kan ingå i beräkningar eller listor även om frågan är irrelevant
- .shown - svaret så som det visas för användaren
- .qid - fråge-ID:t
- .gid - grupp-ID:t
- .sgqa - SGQA-värdet för frågan
- .jsName - det korrekta JavaScript-variabelnamnet för frågan, oavsett om den är definierad på den här sidan eller en annan
- .qseq - frågans ordningsnummer (börjar på 0)
- .gseq - gruppens ordningsnummer (börjar på 0)
- .mandatory - om frågan är obligatorisk (Y/N)
- .question - frågans text
- .relevance - relevansekvationen för frågan
- .grelevance - relevansekvationen för gruppen
- .relevanceStatus - om frågan för tillfället är relevant eller inte (boolesk (kan skilja sig mellan PHP och JS))
- .type - frågetypen (koden med ett tecken)
- Dynamiska ändringar på sidan
- All relevans, alla beräkningar och all anpassning fungerar dynamiskt på en sida - så ändringar i värden uppdaterar sidan direkt
- Frågor visas och döljs alltså dynamiskt beroende på om de är relevanta
- Frågor anpassas också dynamiskt utifrån svar på sidan, så att du kan se löpande summor, anpassade meningar och skräddarsydda rapporter.
- Ny datainmatningsskärm
- Förutom att använda det nuvarande datainmatningssystemet kan du helt enkelt använda Survey-All-In-One.
- Detta stöder relevans och anpassning på sidan, så att datainmatare snabbt kan tabba sig igenom och bara behöver ange de relevanta svaren
- Detta kan vara avgörande om den som matar in data behöver se anpassningen, som också är dynamisk.
- Eliminerar behovet av det mesta av anpassad JavaScript
- EM stöder enkelt komplicerade beräkningar, poängsättning, anpassning och villkorlig logik.
- Vissa saker kräver fortfarande JavaScript (som anpassade layouter och villkorlig döljning av delelement i frågor), men din JavaScript kan använda EM-funktionerna så att du kan komma åt frågor via deras Qcode i stället för SGQA, och komma åt alla frågeegenskaper som listas ovan.
Vilka andra användbara nya funktioner möjliggör EM?
Oavsett om du fortsätter att använda villkorsredigeraren eller skriver relevansekvationer manuellt får du dessa ytterligare fördelar:
- Du kan skapa mer komplexa valideringskriterier
- Alla avancerade frågeattribut (som max_answers, min_num_value_n, max_num_value) kan använda uttryck. Dina minimi-/maximikriterier kan därför enkelt justeras utifrån tidigare svar, även om de finns på samma sida.
- EM hanterar också all validering baserad på reguljära uttryck, så du kan kombinera preg och ekvationsbaserade frågeattribut på ett robust sätt.
- Enkel omordning (eller radering) av frågor och grupper
- Före version 1.92 kunde du inte ordna om frågor eller grupper om LimeSurvey bedömde att omordningen kunde förstöra villkor där de användes. På samma sätt kunde du inte radera frågor om andra frågor var beroende av dem.
- Med EM:s syntaxmarkering är det enkelt att se och kontrollera om du försöker använda frågor innan de har deklarerats. Därför låter vi dig nu ordna om eller radera frågor och grupper när du vill. EM uppdaterar all syntaxmarkering så att du ser möjliga fel.
- Vyn för att ordna om frågor har förbättrats för att underlätta en sådan granskning. Den visar nu frågans relevansekvation och anpassning, så att du direkt kan se om några variabler blir rosa (vilket betyder att de används innan de har deklarerats).
- Navigeringsindexet för frågor/grupper är alltid tillgängligt och korrekt
- Före version 1.92 var dessa index inte tillgängliga om det fanns komplexa villkor
- Med EM kan vi garantera att de är korrekta.
- Deltagare kan till och med hoppa tillbaka till en tidigare fråga, ändra svaret och sedan hoppa framåt (eller skicka)
- När de hoppar framåt validerar EM om alla mellanliggande frågor/grupper.
- Om några frågor blir irrelevanta sätts de till NULL i databasen så att dina data är internt konsekventa
- Om några frågor blir relevanta eller nyligen inte uppfyller regler för obligatoriska frågor eller validering stannar EM på den sidan och tvingar användaren att besvara dessa frågor innan hen hoppar till sin slutdestination.
- Automatisk konvertering av villkor till relevans
- När du uppgraderar din databas genereras relevansekvationer för alla befintliga enkäter som har villkor
- Varje gång du importerar en enkät skapas relevansekvationer vid behov
- Varje gång du lägger till, raderar eller ändrar villkor genererar EM lämplig relevansekvation.
- Praktisk syntaxmarkering
- När EM visar relevansekvationen visas Qcode, även om du angav en SGQA-kod, eftersom vi antar att det är lättare att läsa.
- Alla variabler är färgkodade för att visa om de deklarerades före eller efter den aktuella frågan (eller före eller efter den aktuella gruppen). Det gör att du snabbt kan upptäcka och åtgärda fall där du försöker använda variabler i relevans- (inklusive array_filter), anpassnings- eller valideringsekvationer innan de har deklarerats.
- Om du dessutom håller muspekaren över den färgkodade variabeln ser du de viktigaste metadata om frågan. Dessa inkluderar gruppordning #, frågeordning #, Qcode, frågans text och alla tillgängliga svarsalternativ (om det är en frågetyp med uppräknade svarsalternativ).
- Listan över svarsalternativ använder denna syntax: 'answers':{key:val, ... }.
- key har syntaxen 'scale~code' där scale är svarsskalan (t.ex. för dubbel skala) och code är svarskoden.
- val har syntaxen 'value~shown' där value är utvärderingsvärdet (om utvärderingar används, annars code) (t.ex. Qcode.value) och shown är det visningsvärde som deltagaren ser (t.ex. Qcode.shown)
- Det betyder att många enkäter kan använda beräkningar utan att behöva utvärderingsläge. Om du har uppräknade svarsalternativ som är unika, icke-decimala och icke-negativa kan du helt enkelt göra beräkningar på Qcode.code-värdena.
- Enkel granskning av hela enkätens logik och innehåll
- Det finns en ny funktion, Visa enkätlogik, som låter dig se allt om enkäten (eller gruppen eller frågan) på en enda sida.
- Den visar detaljer på grupp-, fråge-, delfråge- och svarsnivå för det valda omfånget (enkät, grupp eller fråga)
- Den visar också relevans, relevans på delfrågenivå (för array_filter och array_filter_exclude), genererad valideringsekvation (för preg och eventuella valideringsregler som min/max summa/antal värden) och alla frågeattribut som inte är tomma.
- Allt är syntaxmarkerat så att du kan se möjliga syntaxfel (som obalanserade parenteser eller användning av variabler innan de har deklarerats)
- Syntaxmarkeringen underlättar snabb navigering och redigering av enkäten.
- Om du klickar på ett variabelnamn öppnas ett webbläsarfönster (eller en flik) som visar den frågan och låter dig redigera den.
- Om du klickar på ett gruppnamn öppnas ett webbläsarfönster (eller en flik) som visar vyn för att ordna om grupper så att du enkelt kan flytta runt frågor.
- Alla frågeattribut är också syntaxmarkerade. Det låter dig ange och se uttryck i avancerade frågealternativ (som att basera max/min antal/summa av värden på ett uttryck)
- EM:s upphovsman använde en liknande vy (lite renare) för att låta sina samarbetande epidemiologer och etikprövningsnämnd validera och godkänna enkäter med tusentals frågor i starkt förgrenade och anpassade strukturerade intervjuer
Kom igång
Det bästa sättet att komma igång med EM är att:
- Installera den senaste stabila versionen från http://www.limesurvey.org/en/download
- Importera och utforska exempelenkäterna.
- Utforska användningsfall och instruktioner och stegvisa exempel.
- Utforska EM-dokumentationen (denna sida)
- Undersök den inbyggda EM-testsviten
- Från valfri enkät, under verktyg, välj alternativet EM
- Tillgängliga funktioner listar de över 70 funktionerna och deras syntax
- Enhetstester av isolerade uttryck
- visar exempel på användning av alla EM-funktioner och operatorer, samt PHP- och JavaScript-resultaten
- observera att det finns några funktioner som ger olika resultat i PHP- och JavaScript-versionerna, så den här sidan låter dig planera din EM-logik utifrån det.
Vilken funktionalitet utökar/ersätter Expression Manager? (LimeSurvey <= 1.91+)
Villkor => Relevans
Villkor styrde vilka frågor som var synliga. Den allmänna syntaxen var SGQA operator värde, som 111X2X3 == "Y". Villkor kunde kombineras med AND eller OR, men det var svårt att blanda AND och OR. Själva villkoren lagrades i en separat tabell, och en stor del av LimeSurveys kod ägnades åt att hantera villkor. På grund av omfattande databasåtkomst kunde bearbetning av många villkor ge märkbara prestandaproblem. Dessutom fick du ofta inte ordna om eller radera frågor eller grupper när de väl hade villkor tilldelade.
Utvärderingar => Ekvationer och mikroanpassning
Utvärderingar låter användare skapa skalpoäng från en samling frågor. De kunde dock inte ändras dynamiskt på den aktuella sidan, och deras värden lagrades inte i databasen.
Ersättningar => Mikroanpassning
Användare kunde anpassa vissa meddelanden och frågor utifrån tidigare svar. En fråga kunde till exempel vara {TOKEN:FIRSTNAME}, du sa att {SPORT.shown} var din favoritsport. Det var dock inte möjligt att göra villkorlig anpassning (som att säga "Herr" eller "Fru" beroende på personens kön), eller att böja verb och substantiv utan avancerad JavaScript. Författare kunde skapa enkäter som verkade anpassa frågor, men det krävde separata frågor för varje permutation och komplexa villkor för att avgöra vilka frågor som skulle visas.
Validering
Frågor kunde valideras med reguljära uttryck, minimi-/maximivärden, eller genom att låta ett svar fungera som minimi- eller maximivärde. Valideringar kunde dock inte baseras på beräkningar av andra variabler utan avancerad JavaScript.
Ekvationer
Ekvationer stöddes inte utan avancerad JavaScript.
Frågetypen Ekvation
Ekvationer kunde inte sparas i databasen (t.ex. slutpoängen för en utvärdering) utan avancerad JavaScript.
Hur ersätter/utökar Expression Manager den funktionaliteten?
Expression Manager är en ny kärnmodul i LimeSurvey som gör det mycket enklare att stödja den typ av komplex funktionalitet som tidigare krävde egen JavaScript. Den ersätter också hur LimeSurvey för närvarande hanterar villkor och utvärderingar.
Ny terminologi när man talar om Expression Manager (EM)
EM "tänker" på sin funktionalitet i följande termer:
- Relevansbaserad förgrening - om en fråga är relevant ställs den, annars inte (t.ex. görs den osynlig och markeras som NULL i databasen). Det finns ett nytt relevansfält för alla frågetyper och även för varje grupp (så att du kan tillämpa en uppsättning villkor på en hel grupp utan att behöva kopiera samma villkor till varje fråga, och/eller kombinera villkorslogik på grupp- och frågenivå).
- Anpassning - När du vet vilka frågor som ska ställas anger anpassning (ibland kallad piping) hur frågan ska ställas. Det gör att du kan stödja inte bara enkel ersättning (som {TOKEN:FIRSTNAME}), utan även böjning av verb och substantiv utifrån kön eller antal hos dina deltagare. Du kan också ändra meddelandet du visar för en deltagare beroende på om (eller hur) hen besvarade andra frågor.
- Ekvationer - EM lägger till en ny frågetyp som heter Ekvation och som lagrar resultatet av ett uttryck. Dessa ekvationsresultat beräknas och skrivs till databasen, även om du döljer dem på sidan. De är därför användbara för dolda poängberäkningar, navigering baserad på komplexa ekvationer, utvärderingar och rapporter som ska genereras och vara lätt tillgängliga i databasen.
Relevans och kaskadrelevans
Varje frågetyp har nu ett relevansalternativ som styr om frågan visas. EM bearbetar varje relevansekvation i den ordning de ska visas i enkäten. Om uttrycket är sant (eller saknas - för att stödja äldre enkäter) visas frågan. Om den inte är relevant döljs frågan och värdet sätts till NULL i databasen. Om det inte finns några relevanta frågor i en grupp hoppas hela gruppen över.
Dessutom, om någon av variablerna i ett uttryck är irrelevant utvärderas uttrycket alltid till falskt. Detta möjliggör kaskadrelevans så att du inte behöver skriva mycket långa relevansekvationer för varje fråga.
Säg att du har 5 frågor Q1–Q5 och bara vill visa Q2 om Q1 besvarades, och Q3 om Q2 besvarades, osv. Relevansekvationerna kan då vara:
| Frågekod | Relevans | Fråga |
|---|---|---|
| Q1 | 1 | Vad heter du? |
| Q2 | Q1 | {Q1}, hur gammal är du? |
| Q3 | Q2 | Du är alltså {Q2} år gammal. Är du gift? |
| Q4 | Q3 == "Y" | {Q1}, hur länge har du varit gift? |
| Q5 | Q4 | Hur många barn har du, {Q1}? |
Relevansberäkningarna fungerar också i JavaScript - så du kan lägga alla ovanstående frågor på en sida och det fungerar ändå som förväntat. EM ersätter faktiskt helt hur EM bearbetar enkätformaten enkät, grupp och en fråga i taget. De använder nu alla exakt samma navigeringsmotor, så de fungerar identiskt oavsett enkätstil.
Så länge du är kvar på samma sida finns alla data du har angett kvar, fast dolda. Om du alltså anger viss information, sedan väljer ett alternativ som gör dem irrelevanta och därefter gör dem relevanta igen, finns dina svar fortfarande kvar. Så snart du går till en annan sida går dock alla irrelevanta svar förlorade för att bevara datauppsättningens integritet.
Relevans på gruppnivå
Expression Manager stöder även relevans på gruppnivå. Detta gör det enklare att implementera upprepningar (loopar). Anta att du vill samla in information om upp till 10 enheter (till exempel produkter eller personer i ett hushåll), där du först avgör hur många enheter som behöver följas upp (till exempel genom att fråga hur många personer som bor i hushållet, eller genom att låta respondenterna markera vilka produkter de gillar i en lång lista). När du vet hur många enheter som behöver följas upp kan du använda relevans på gruppnivå som {count >= 1}, {count >=2}, ... {count >= 10} för var och en av de 10 grupperna med uppföljningsfrågor. I varje grupp kan du ha villkorlig logik på frågenivå (t.ex. könsspecifika eller åldersspecifika uppföljningsfrågor för varje person). Relevansekvationerna på fråge- och gruppnivå kombineras med AND för att avgöra vad som ska visas.
Anpassning / Piping
Allt som står inom klammerparenteser behandlas nu som ett uttryck (med ett undantag som beskrivs nedan). Uttryck har tillgång till alla LimeReplacementFields, alla variabler (via flera alias), alla typiska operatorer i ekvationer (matematiska, logiska och jämförande) samt dussintals funktioner (som till och med fungerar dynamiskt på klientsidan).
Med dessa ekvationer kan du till exempel:
- Visa anpassade meddelanden till respondenterna villkorligt, baserat på tidigare svar
- Skapa utvärderingar och visa utvärderingsresultat (eller grena villkorligt eller visa meddelanden) baserat på dessa resultat, helt utan att använda själva utvärderingsmodulen
- Böja verb och substantiv i frågor, svar och rapporter.
- Visa sammanfattningar av svar före sidan "Visa dina svar" i slutet av enkäten
Ekvationer
Det finns en ny frågetyp som heter Ekvation. Den liknar en Boilerplate-fråga, men värdet på det som visas lagras i databasen. Om frågetexten för en ekvationsfråga innehåller en utvärderingsberäkning lagras alltså det värdet i databasen i en variabel som kan visas i offentlig eller privat statistik.
Detta löser ett vanligt önskemål om att lagra utvärderingspoäng i databasen
Syntax
Allt som står inom klammerparenteser betraktas nu som ett uttryck (med ett undantag: det får inte finnas inledande eller avslutande blanksteg – detta behövs för att Expression Manager inte ska försöka bearbeta inbäddad JavaScript).
Observera att uttryck får sträcka sig över flera rader, så länge det inte finns blanksteg efter den inledande klammerparentesen eller före den avslutande klammerparentesen. Detta är särskilt användbart för nästlade if()-satser som den här:
{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',
''
)
)
)
)
)
)
)
)}
- Alla vanliga matematiska operatorer (t.ex. +,-,*,/,!)
- Alla vanliga jämförelseoperatorer (t.ex. <,<=,==,!=,>,>=, plus dessa motsvarigheter: lt,le,eq,ne,gt,ge)
- Parenteser (så att du kan gruppera deluttryck)
- Villkorsoperatorer (t.ex. &&,| | och dessa motsvarigheter: and,or)
- Strängar inom enkla och dubbla citattecken (som vardera kan innehålla strängar med den andra citattecknetypen)
- Kommaoperator (så att du kan ha en lista med uttryck och bara returnera det sista resultatet)
- Tilldelningsoperator (=)
- Fördefinierade variabler (för att referera till frågor, frågeattribut och svar) – t.ex. alla SGQA-koder
- Fördefinierade funktioner (det finns redan över 70, och det är enkelt att lägga till fler)
Operatorer
EM-syntaxen följer vanlig operatorprioritet:
| Nivå | Operator(er) | Beskrivning |
|---|---|---|
| 1 | () | parenteser för gruppering eller anrop av funktioner |
| 2 | ! - + | unära operatorer: icke, negation, unärt plus |
| 3 | * / | multiplikation, division |
| 4 | + - | addition, subtraktion |
| 5 | < <= > >= lt le gt ge | relativa jämförelser |
| 6 | == != eq ne | likhetsjämförelser |
| 7 | and | logiskt AND |
| 8 | or | logiskt OR |
| 9 | = | tilldelningsoperator |
| 10 | , | kommaoperator |
Varning för plusoperatorn (+)
För att JavaScript och PHP ska fungera likadant utför plusoperatorn (+) addition om båda operanderna är numeriska, men sammanfogning om båda delarna är icke-numeriska strängar. Vi rekommenderar dock att du använder funktionen join() för sammanfogning och funktionen sum() för addition, eftersom det gör din avsikt tydligare och undviker oväntade resultat om du förväntade dig strängar men fick tal (eller tvärtom).
Varning för felmatchning mellan tal och sträng samt alfabetisk jämförelse
När du vill jämföra värden med relativa jämförelser eller likhetsjämförelser bör du vara uppmärksam på typfelmatchning. Ett värde som en användare har angett eller en vald svarskod kan användas som ett tal om det tydligt är ett tal.
Om du omger ett av värdena med " tvingas jämförelsen att göras som text (alfabetisk jämförelse). Om du vill jämföra numeriskt ska du aldrig omge talet med citattecken, ".
Till exempel är Q0.NAOK > "50" sant om Q0.NAOK är en numerisk fråga med värdet 9. Detta beror på att operatorn > antar att jämförelsen är alfabetisk och inte numerisk.
För att vara säker på att jämföra heltalsvärden kan du använda intval(Q0.NAOK) > 50, men kom ihåg att om Q0.NAOK inte är ett tal (tomt eller en sträng) så är intval(Q0.NAOK) == 0. För att jämföra strängvärden ("A" < "B") använder du strcmp direkt: strcmp(Q0.NAOK,"B") eller strcmp(Q0.NAOK,"A5").
Observera vid användning av tilldelningsoperatorn (=)
Observera att du bör undvika tilldelningsoperatorer om det inte är absolut nödvändigt, eftersom de kan ge oväntade sidoeffekter. Om du till exempel ändrar värdet på ett tidigare svar beräknas inte den kaskadande relevans- och valideringslogiken mellan den frågan och den aktuella frågan om, så du kan få internt inkonsekventa data (t.ex. frågor som förblir besvarade men som borde ha satts till NULL, eller frågor som hoppas över men som borde ha besvarats). Om du vill tilldela ett värde till en variabel bör du i allmänhet skapa en fråga av typen Ekvation och använda ett uttryck för att ange dess värde. Det finns dock sällsynta tillfällen då man verkligen behöver den här operatorn, så vi har gjort den tillgänglig.
För att uppmärksamma dig på den här operatorn visas den i röd text i syntaxekvationerna (så att du inte förväxlar den med "==")
Använda tilldelningsoperatorn
De främsta anledningarna till att du kan vilja använda tilldelning är:
- Du behöver ange standardvärdet för en fråga som inte accepterar standardvärden via ekvation (till exempel radioknappslista, där användargränssnittet låter dig välja ett av svarsalternativen men inte låter dig ange en ekvation). Var dock försiktig, eftersom LimeSurvey inte kan validera att din ekvation genererar ett av de tillåtna svaren för den frågan.
- Du behöver tvinga fram en ändring av svaret på en tidigare fråga baserat på ett senare svar
- Du behöver en komplex kvot: använd en dold envalsfråga för kvoten och ange den med tilldelning
- osv...
Du kan använda hela Expression Manager-systemet för detta ändamål.
Några exempel:
- Ange svaret på en kort textfråga med gemener:
{QCODE=strtolower(QCODE.NAOK)} - Ange ett standardsvar för en samlingsfrågetyp i början av en enkät:
{Q1_SQ1=((is_empty(Q1_SQ1.NAOK),"A99",Q1_SQ1.NAOK)} - Ange ett standardsvar för en frågetyp med textsamling i början av en enkät:
{Q1_SQY1_SQX1 = ((is_empty(Q1_SQY1_SQX1.NAOK),"Inserted answer", Q1_SQY1_SQX1.NAOK)} - Ange ett svar med villkor:
{QCODE=if(YesNo="Y","A1","")}
XSS-säkerhet
Med XSS-skydd aktiverat kan vissa funktioner i Expression Manager inte användas:
- att starta en HTML-tagg i ett uttryck men avsluta den i ett annat uttryck
- att använda ett komplext uttryck i en URL.
Exempel och lösning
{if( 1 ,"<strong>","")}information{if( 1 ,"</strong>","")}fungerar inte med XSS-skydd. Här kan du använda{if(1,"<strong>information</strong>","information")}<a href="/script.php?value={if(QCODE == "Y","yes","no")}">next</a>. Här kan du använda en ekvationsfråga, eftersom det är tillåtet att använda en komplett frågekod:<a href="/script.php?value={EQUATION.NAOK}">next</a>
Åtkomst till variabler
Expression Manager ger skrivskyddad åtkomst till de variabler du kan behöva. För bakåtkompatibilitet ger det åtkomst till följande:
- TOKEN:xxx - värdet för en TOKEN (t.ex. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (endast för enkäter som INTE är anonyma).
- QCODE.shown - visningsvärdet för ett svar (t.ex. "Ja") med hjälp av Expression Manager.
- Alla {XXX}-värden som används av mallar.
- I frågetext kan du använda {QID}, som ersätts av fråge-ID, och {SGQ}, som ersätts av frågans SGQA.
Dessutom låter Expression Manager dig referera till variabler med frågekoden (kolumnen 'title' i frågetabellen i databasen). Det är också den variauetikett som används när du exporterar dina data till SPSS, R eller SAS. Om du till exempel har frågor om namn, ålder och kön kan du kalla variablerna name, age och gender i stället för 12345X13X22, 12345X13X23 och 12345X13X24. Det gör ekvationer lättare för alla att läsa och validera, och det gör det möjligt att flytta runt frågor utan att behöva hålla reda på grupp- eller frågenummer.
Viktigt: Det är bara säkert att referera till variabler som finns på föregående sidor eller i föregående frågor.
Expression Manager låter dig dessutom komma åt många av frågans egenskaper:
| Syntax | Betydelse | Exempel | Exempelresultat |
|---|---|---|---|
| Qcode | ett alias för Qcode.code | {implode(',',name,gender)} | 'Tom','M' |
| Qcode.code | den valda svarskoden för frågan om den är relevant (annars tom), eller textvärdet om det inte är en kodad fråga | {implode(',',name.code,gender.code)} | 'Tom','M' |
| Qcode.NAOK | samma som Qcode - se beskrivningen av NAOK | {gender.NAOK} | 'M' |
| Qcode.value | utvärderingsvärdet för frågan om den är relevant (annars tom), eller textvärdet om det inte är en kodad fråga | {gender.value} | '1' |
| Qcode.valueNAOK | samma som Qcode.value - se beskrivningen av NAOK | {gender.valueNAOK} | '1' |
| Qcode.shown | visningsvärdet för frågan | {implode(',',name.shown,gender.shown)} | 'Tom','Male' |
| Qcode.question | frågans text | {gender.question} | 'What is your gender?' |
| Qcode.mandatory | om frågan är obligatorisk (Y/N) | {gender.mandatory} | 'N' |
| Qcode.qid | det interna frågenumret (inte det sekventiella numret) | {gender.qid} | 337 |
| Qcode.type | frågetypen | {gender.type} | 'G' |
| Qcode.jsName | det korrekta JavaScript-namnet för frågan, oavsett om den är deklarerad på den här sidan eller inte | {gender.jsName} | 'java1827X3X337' |
| Qcode.gid | det interna gruppnumret (inte det sekventiella numret) | {gender.gid} | 3 |
| Qcode.qseq | frågans sekventiella nummer, med start från 0 | {gender.qseq} | 5 |
| Qcode.gseq | gruppens sekventiella nummer, med start från 0 | {gender.gseq} | 1 |
| Qcode.relevanceStatus | om frågan för närvarande är relevant (0 eller 1) | {gender.relevanceStatus} | 1 |
| Qcode.relevance | relevansekvationen på frågenivå | {gender.relevance} | '!is_empty(name)' |
| Qcode.grelevance | relevansekvationen på gruppnivå | {gender.grelevance} | 'num_children >= 5' |
| Qcode.sgqa | SGQA-värdet för frågan | {gender.sgqa} | '1827X3X337' |
Problem med HTML-redigeraren
Om du använder HTML-redigeraren ersätts vissa tecken med HTML-entiteter.
- & ersätts med &
- < ersätts med <
- > ersätts med >
Om du använder HTML-redigeraren måste du använda:
- and för &
- lt för <
- le för <=
- gt för >
- ge för >=
Namngivning av Qcode-variabler
Här beskrivs hur du konstruerar en Qcode (och kommer åt vissa egenskaper) per frågetyp. I allmänhet konstrueras Qcodes så här:
QuestionCode . '_' . SubQuestionCode . '_' . ScaleId
Delfrågekod och skal-ID behöver användas eller inte beroende på frågetyp - se tabellen nedan. För comment och other är frågekoderna QuestionCode_comment och QuestionCode_other
| Typ | Beskrivning | Kod | Delfrågor | Alternativ för svar | Skalor | Svarskod | Visat svar | Relevans |
|---|---|---|---|---|---|---|---|---|
| 5 | 5-punktsval, alternativknappar | Q1 | 1-5 | {Q1} | {Q1.shown} | {Q1==3} | ||
| B | Samling (10-punktsval), alternativknappar | Q2 | L1-L6 | 1-10 | {Q2_L2} | {Q2_L2.shown} | {Q2_L2==7} | |
| A | Samling (5-punktsval), alternativknappar | Q3 | 1-5 | 1-5 | {Q3_1} | {Q3_1.shown} | {Q3_1>=3} | |
| 1 | Samling (flexibla etiketter), dubbel skala | Q4 | sq1-sq5 | 0:a1-a3 | 1:b1-b3 | {Q4_sq1_0} | {Q4_sq1_1.shown} | {Q4_sq1_1=='b2'} |
| H | Samling (flexibel) - kolumnformat | Q5 | 1-5 | s,m,t | {Q5_1} | {Q5_1.shown} | {Q5_1=='s'} | |
| F | Samling (flexibel) - radformat | Q6 | F1-F5 | 1-5 | {Q6_F3} | {Q6_F3.shown} | {Q6_F3==4} | |
| E | Samling (öka, samma, minska), alternativknappar | Q7 | 1-7 | I,S,D | {Q7_4} | {Q7_4.shown} | {Q7_4=='D'} | |
| : | Samling (flera flexibla) 1 till 10 | Q8 | ls1,todo,ls2 | min,max,avg | {Q8_ls1_max} | {Q8_ls2_avg.shown} | {Q8_ls2_min==7} | |
| ; | Samling (flera flexibla) text | Q9 | hp,st,sw | 1st,2nd,3rd | {Q9_hp_3rd} | {Q9_hp_3rd.shown} | {Q9_hp_3rd=='Peter'} | |
| C | Samling (ja/osäker/nej), alternativknappar | Q10 | 1-5 | Y,N,U | {Q10_1} | {Q10_1.shown} | {Q10_3=='Y'} | |
| X | Standardtextfråga | Q11 | {Q11.shown} | |||||
| D | Datum | Q12 | {Q12} | {Q12.shown} | ||||
| * | Ekvation | Q13 | {Q13} | {Q13.shown} | {Q13>5} | |||
| ~124~ | Filuppladdning (registrerar antalet uppladdade filer) | Q14 | {Q14} | {Q14>0} | ||||
| G | Rullgardinsmeny för kön | Q15 | M,F | {Q15} | {Q15.shown} | {Q15=='M'} | ||
| U | Mycket lång fritext | Q16 | {Q16} | {Q16.shown} | {strlen(Q16)>100} | |||
| I | Språkfråga | Q17 | {Q17} | {Q17.shown} | {Q17=='en'} | |||
| ! | Lista - rullgardinsmeny | Q18 | 1-5 | {Q18} | {Q18.shown} | {Q18==3} | ||
| L | Lista, rullgardinsmeny/alternativknappar | Q19 | A-Z | {Q19} | {Q19.shown} | {Q19=='X'} | ||
| O | Lista med kommentarer, rullgardinsmeny/alternativknappar + textområde | Q20 | A-F | {Q20},{Q20comment} | {Q20.shown} | {Q20=='B'} | ||
| T | Lång fritext | Q21 | {Q21} | {Q21.shown} | {strstr(Q21,'hello')>0} | |||
| M | Flervalsfråga, kryssrutor | Q22 | A-F, other | {Q22_E}, {Q22_other} | {Q22_E.shown}, {Q22_other.shown} | {Q22_E=='Y'} | ||
| P | Flervalsfråga med kommentarer, kryssruta + text | Q23 | A-F | {Q23_D}, {Q23_Dcomment} | {Q23_D.shown} | {!is_empty(Q23)} | ||
| K | Flera numeriska frågor | Q24 | self,mom,dad | {Q24_self} | {Q24_self.shown} | {Q24_self>30} | ||
| Q | Flera korta textsvar | Q25 | A-F | {Q25_B} | {Q25_B.shown} | {substr(Q25_B,1,1)=='Q'} | ||
| N | Numerisk frågetyp | Q26 | {Q26} | {Q26.shown} | {Q26 > 30} | |||
| R | Rangordning | Q27 | 1-4 | {Q27_1} | {Q27_1.shown} | {Q27_1==3} | ||
| S | Kort fritext | Q28 | {Q28} | {Q28.shown} | {Q28=='mine'} | |||
| Y | Ja/Nej, alternativknappar | Q29 | {Q29} | {Q29.shown} | {Q29=='Y'} |
De reserverade variablerna 'this', 'self' och 'that'
Ofta vill du utvärdera alla delar av en fråga, till exempel räkna hur många delfrågor som har besvarats eller summera poängen. Andra gånger vill du bara bearbeta vissa rader eller kolumner i en fråga (till exempel hämta rad- eller kolumnsummor och lagra dem i databasen). De här reserverade variablerna gör det enkelt.
Variabeln 'this' används uteslutande i de avancerade frågealternativen "Whole question validation equation" och "Sub-question validation equation". Den expanderas till variabelnamnen för var och en av cellerna i frågorna. Om du vill se till att varje värde är större än tre ställer du alltså in "Sub-question validation equation" på (this > 3).
Variablerna 'self' och 'that' är kraftfullare och fungerar som makron som expanderas innan ekvationerna bearbetas. Syntaxvalen är:
- self
- self.suffix
- self.sub-selector
- self.sub-selector.suffix
suffix är något av de vanliga Qcode-suffixen (t.ex. NAOK, value, shown)
sub-selector är något av följande:
- comments - endast delfrågor som är kommentarer (t.ex. från flervalsfråga med kommentarer och lista med kommentarer)
- nocomments - endast delfrågor som inte är kommentarer
- sq_X - där X är en rad- eller kolumnidentifierare. Endast delfrågor som matchar mönstret X väljs. Observera att sökningen görs på hela kodidentifieraren, och att sq_X sedan matchar och inkluderar delfrågorna nX, X och Xn (om du t.ex. använder sq_1 inkluderas delfrågorna a1, 1a, 1, 11 eller 001). Var uppmärksam på frågetypen med dubbel skala, där delfrågekoderna är QCODE_SQCODE_1 och QCODE_SQCODE_1, och på rangordningsfrågor, där delfrågekoderna är QCODE_1, QCODE_2 ....
- nosq_X - där X är en rad- eller kolumnidentifierare. Endast delfrågor som inte matchar mönstret X väljs. Observera att sökningen görs på hela kodidentifieraren, och att nosq_X sedan matchar och inte inkluderar delfrågorna nX, X och Xn
Exempel:
- Har någon del av en fråga besvarats? {count(self.NAOK)>0}
- Vad är utvärderingspoängen för den här frågan? {sum(self.value)}
Du kan också använda dem för att få rad- och kolumnsummor. Säg att du har en samling med tal med raderna A-E och kolumnerna 1-5.
- Vad är totalsumman? {sum(self.NAOK)}
- Vad är summan för rad B? {sum(self.sq_B.NAOK)}
- Vad är summan för kolumn 3? {sum(self.sq_3.NAOK)}
Variabeln 'that' liknar variabeln 'self', men låter dig referera till andra frågor. Syntaxen är:
- that.qname
- that.qname.suffix
- that.qname.sub-selector
- that.qname.sub-selector.suffix
qname är frågenamnet utan några delfrågetillägg. Om du till exempel skapar en fråga 'q1' är det dess qname
Exempel:
- Har någon del av fråga q1 besvarats? {count(that.q1.NAOK)>0}
- Vad är utvärderingspoängen för q2? {sum(that.q2.NAOK)}
- Vad är totalsumman för q3? {sum(that.q3.NAOK)}
- Vad är summan för rad C i q4? {sum(that.q4.sq_C.NAOK)}
- Vad är summan för kolumn 2 i q4? {sum(that.q4.sq_2.NAOK)}
Variablerna 'self' och 'that' kan användas i alla relevans-, valideringsuttryck och all anpassning.
En sak att tänka på är att funktionen Show Logic File visar det expanderade värdet av 'self' och 'that'. På så sätt kan du se den faktiska ekvation som kommer att genereras, så att du (och Expression Manager) kan validera att variablerna finns. Det kan verka förvirrande eftersom du kan se mycket långa ekvationer. Om du redigerar frågan ser du dock den ursprungliga ekvationen med 'self' och/eller 'that'
Observera också att du inte bör använda dessa variabler om du (a) uttryckligen vill namnge varje variabel som används i en ekvation, eller (b) använder variabler som saknar delfrågor (t.ex. frågor med ett enda svar). I sådana fall är det överflödigt att lägga prefixet 'that' framför en variabel, och du riskerar att få oväntade resultat.
Användning av NAOK
NAOK --> "Not Applicable" (NA) är i sin ordning (OK)
Att använda NAOK innebär att alla eller några av variablerna är irrelevanta (t.ex. "Not Applicable" (NA) är i sin ordning (OK)).
När du använder en variabel från en fråga i en ekvation gäller följande: om frågan (eller delfrågan) är dold på grund av ett villkor inaktiveras hela ekvationen.
Till exempel: count(Q1_SQ1,Q1_SQ2,Q1_SQ3,Q1_SQ4) ger alltid en tom sträng om någon delfråga i Q1 har filtrerats bort. För att räkna antalet markerade delfrågor i en sådan fråga kan du använda count(Q1_SQ1.NAOK,Q1_SQ2.NAOK,Q1_SQ3.NAOK,Q1_SQ4.NAOK). Om delfrågan är dold returnerar Expression Manager en tom sträng.
Utan NAOK: om en fråga eller en delfråga är dold returnerar Expression Manager alltid en tom sträng, vilket motsvarar false.
.shown använder alltid NAOK-systemet (tom sträng om frågan är dold), men om du behöver svarskoden är det alltid en bra idé att lägga till .NAOK efter frågekoden, om du inte behöver något annat och vet vad du gör.
Ytterligare ett exempel och mer information finns under Överstyrning av kaskadvillkor
Åtkomst till funktioner
Expression Manager ger tillgång till matematiska funktioner, strängfunktioner och användardefinierade funktioner, enligt nedan. Det finns motsvarigheter i PHP och JavaScript för dessa funktioner så att de fungerar likadant på serversidan (PHP) och klientsidan (JavaScript). Det är enkelt att lägga till nya funktioner.
Implementerade funktioner
Följande funktioner är för närvarande tillgängliga:
| Funktion | Betydelse | Syntax |
|---|---|---|
| abs | Absolutvärde | number abs(number) |
| acos | Arcus cosinus | number acos(number) |
| addslashes | Sätt snedstreck framför specialtecken i en sträng | string addslashes(string) |
| asin | Arcus sinus | number asin(number) |
| atan | Arcus tangens | number atan(number) |
| atan2 | arcus tangens med två variabler | number atan2(number, number) |
| ceil | Avrunda decimaler uppåt | number ceil(number) |
| checkdate | Returnerar sant (1) om det är ett giltigt datum i den gregorianska kalendern | bool checkdate(month,day,year) |
| convert_value | Konvertera ett numeriskt värde med hjälp av en inputTable och en outputTable med numeriska värden | number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList) |
| cos | Cosinus | number cos(number) |
| count | räkna antalet besvarade (icke-tomma) frågor i listan | number count(arg1, arg12, ..., argN) |
| countif | Räkna antalet besvarade frågor i listan som är lika med det första argumentet | number countif(matches, arg1, arg2, ... argN) |
| countifop | Räkna antalet besvarade frågor i listan som uppfyller kriteriet (arg op value) | number countifop(op, value, arg1, arg2, ... argN) |
| date | Ange format för lokalt datum/tid | string date(format [, timestamp=time()]) |
| exp | Beräkna exponenten av e | number exp(number) |
| fixnum | Visa tal med komma som decimaltecken, om det behövs | string fixnum(number) |
| floor | Avrunda decimaler nedåt | number floor(number) |
| gmdate | Formatera en tidsangivelse (datum/tid) angiven i GMT | string gmdate(format [, timestamp=time()]) |
| html_entity_decode | Konvertera alla HTML-entiteter till motsvarande tecken (använder alltid ENT_QUOTES och UTF-8) | string html_entity_decode(string) |
| htmlentities | Konvertera alla tecken som har en motsvarande HTML-entitet till HTML-entiteter (använder alltid ENT_QUOTES och UTF-8) | string htmlentities(string) |
| expr_mgr_htmlspecialchars | Konvertera specialtecken till HTML-entiteter (använder alltid ENT_QUOTES och UTF-8) | string htmlspecialchars(string) |
| expr_mgr_htmlspecialchars_decode | Konvertera särskilda HTML-entiteter tillbaka till tecken (använder alltid ENT_QUOTES och UTF-8) | string htmlspecialchars_decode(string) |
| idate | Formatera en lokal tidsangivelse (tid/datum) som ett heltal | string idate(string [, timestamp=time()]) |
| if (Updated in 3.0.2 ) | if i Excel-stil (test,result_if_true[,result_if_false = ""]) | if(test,result_if_true[,result_if_false = ""]) |
| implode | Slå samman element i en lista med en sträng som avskiljare | string implode(glue,arg1,arg2,...,argN) |
| intval | Returnera heltalsvärdet från en variabel | int intval(number [, base=10]) |
| is_empty | Avgör om en variabel anses vara tom | bool is_empty(var) |
| is_float | Avgör om typen på en variabel är flyttal | bool is_float(var) |
| is_int | Avgör om typen på en variabel är heltal | bool is_int(var) |
| is_nan | Avgör om ett värde är ett tal eller ej | bool is_nan(var) |
| is_null | Avgör om en variabel är NULL eller ej | bool is_null(var) |
| is_numeric | Avgör om en variabel är ett tal eller en numerisk sträng | bool is_numeric(var) |
| is_string | Avgör om typen på en variabel är sträng | bool is_string(var) |
| join (New in 2.0 build 130129) | Slå samman element till en ny sträng | join(arg1, arg2, ... argN) |
| list | Returnera en kommaseparerad lista med icke-tomma värden | string list(arg1, arg2, ... argN) |
| listifop (New in 3.16.1 ) | Returnera en lista, avskild med 'glue', över den angivna frågeegenskapen (retProp) för de frågor i listan som uppfyller kriteriet (cmpProp op value) | string listifop(cmpProp, op, value, retProp, glue, sgqa1, sgqa2, ... sgqaN) |
| log | Logaritmen av number med angiven bas, eller den naturliga logaritmen om ingen bas anges. | number log(number,base=e) |
| ltrim | Ta bort blanksteg (eller andra tecken) från början av en sträng | string ltrim(string [, charlist]) |
| max | Hitta det högsta värdet | number max(arg1, arg2, ... argN) |
| min | Hitta det minsta värdet | number min(arg1, arg2, ... argN) |
| mktime | Hämta UNIX-tidsstämpel för ett datum (vart och ett av de 6 argumenten är valfritt) | number mktime([hour [, minute [, second [, month [, day [, year ]]]]]]) |
| modulo-function | Modulofunktionen stöds inte ännu. Du kan använda funktionen floor() i stället | floor(x/y)==(x/y) |
| nl2br | Infogar HTML-radbrytningar före alla radbrytningar i en sträng | string nl2br(string) |
| number_format | Formatera ett tal med gruppering i tusental | string number_format(number) |
| pi | Värde för pi | number pi() |
| pow | Exponent | number pow(base, exp) |
| quoted_printable_decode | Konvertera en quoted-printable-sträng till en 8-bitarssträng | string quoted_printable_decode(string) |
| quoted_printable_encode | Konvertera en 8-bitarssträng till en quoted-printable-sträng | string quoted_printable_encode(string) |
| quotemeta | Sätt citattecken kring speciella tecken | string quotemeta(string) |
| rand | Generera ett slumpmässigt heltal, se det här exemplet | int rand() OR int rand(min, max) |
| regexMatch | jämför en sträng med ett reguljärt uttryck | bool regexMatch(pattern,input) |
| round | Avrunda ett decimaltal (med valfri precision om sådan angivits) | number round(val [, precision]) |
| rtrim | Ta bort blanksteg (eller andra tecken) från slutet av en sträng | string rtrim(string [, charlist]) |
| sin | Sinus | number sin(arg) |
| sprintf | Returnera en formaterad sträng | string sprintf(format, arg1, arg2, ... argN) |
| sqrt | Kvadratrot | number sqrt(arg) |
| stddev | Beräkna standardavvikelsen i stickprovet för listan med tal | number stddev(arg1, arg2, ... argN) |
| str_pad | Fyll ut en sträng till en viss längd med en annan sträng | string str_pad(input, pad_length [, pad_string]) |
| str_repeat | Upprepa en sträng | string str_repeat(input, multiplier) |
| str_replace | Ersätt alla förekomster av söksträngen med ersättningssträngen | string str_replace(search, replace, subject) |
| strcasecmp | Skiftlägesokänslig strängjämförelse (binary safe) | int strcasecmp(str1, str2) |
| strcmp | Strängjämförelse (binary safe) | int strcmp(str1, str2) |
| strip_tags | Ta bort HTML- och PHP-taggar teckensträng | string strip_tags(str, allowable_tags) |
| stripos | Hitta positionen för första förekomsten av en unicode-sträng, utan hänsyn till skiftläge (börjar på 0, returnerar false om den inte hittas) | int stripos(haystack, needle [, offset=0]) |
| stripslashes | Tar bort citattecken från en sträng (un-quote) | string stripslashes(string) |
| stristr | Skiftlägesokänslig strstr | string stristr(haystack, needle [, before_needle=false]) |
| strlen | Beräkna längden på en sträng | int strlen(string) |
| strpos | Hitta positionen för första förekomsten av en unicode-sträng (börjar på 0, returnerar false om den inte hittas) | int strpos(haystack, needle [ offset=0]) |
| strrev | Vänd på en sträng | string strrev(string) |
| strstr | Hitta första förekomsten av en sträng | string strstr(haystack, needle[, before_needle=false]) |
| strtolower | Gör om en sträng till gemener | string strtolower(string) |
| strtotime | Tolka nästan vilken engelsk textbeskrivning av datum och tid som helst till en Unix-tidsstämpel | int strtotime(string) |
| strtoupper | Gör om en sträng till versaler | string strtoupper(string) |
| substr | Returnera en del av en unicode-sträng | string substr(string, start [, length]) |
| sum | Beräkna summan av värdena i en lista/array? | number sum(arg1, arg2, ... argN) |
| sumifop | Summera värdena för besvarade frågor i listan som uppfyller kriteriet (arg op value) | number sumifop(op, value, arg1, arg2, ... argN) |
| tan | Tangens | number tan(arg) |
| time | Returnera nuvarande tidsstämpel (UNIX timestamp) | number time() |
| trim | Ta bort blanksteg (eller andra tecken) från början och slutet av en sträng | string trim(string [, charlist]) |
| ucwords | Gör första tecknet i varje ord i en sträng till versal | string ucwords(string) |
| unique | Returnera sant om alla icke-tomma svar är unika | boolean unique(arg1, ..., argN) |
Funktioner som är planerade eller övervägs
Andra funktioner som är planerade (eller övervägs) men som ännu inte är implementerade är bland annat följande. Några av dem finns med för bakåtkompatibilitet med andra enkätverktyg.
| Syntax | Betydelse | Kommentarer |
|---|---|---|
| e() | returnerar värdet av e | |
| formatDate(X,PAT) | returnerar textvärdet av datumet X formaterat enligt Javas datumformatmönster PAT | |
| formatNumber(X,PAT) | returnerar textvärdet av talet X formaterat enligt Javas talformatmönster PAT | |
| getAnsOption(X) | Core plugin ExpressionAnswerOptions | |
| getAnsOption(X,Y) | Core plugin ExpressionAnswerOptions | |
| getRelevance(X) | returnerar relevansekvationen för fråga X | |
| getStartTime() | returnerar datumet som motsvarar systemtiden då intervjun startades | |
| getType(X) | returnerar datatypens namn som text - t.ex. *NA* om isNA() | |
| gotoFirst() | hoppar till den första relevanta uppsättningen frågor - detta bryter mot systemets normala flöde | |
| gotoNext() | hoppar till nästa relevanta uppsättning frågor - detta bryter mot systemets normala flöde | |
| gotoPrevious() | hoppar till föregående relevanta uppsättning frågor - detta bryter mot systemets normala flöde | |
| isAsked(X) | returnerar sant om svaret varken är *NA*, *INVALID* eller *UNASKED* | |
| isInvalid(X) | returnerar sant om svaret är av typen *INVALID* | |
| isNA(X) | returnerar sant om svaret är av typen *NA* | |
| isNotUnderstood(X) | returnerar sant om svaret är av typen *HUH* | |
| isRefused(X) | returnerar sant om svaret är av typen *REFUSED* | |
| isSpecial(X) | returnerar sant om svaret är av typen *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN* eller *HUH* | |
| isUnknown(X) | returnerar sant om svaret är av typen *UNKNOWN* | |
| jumpTo(X) | hoppa till gruppen som innehåller den angivna frågan -- detta bryter mot systemets normala flöde | |
| jumpToFirstUnasked() | hoppa till den första ostälda frågan |
|
| lastIndexOf(X,Y) | returnerar det sista indexet (med start från 0) för texten Y i texten X. Returnerar -1 om Y inte finns i X | |
| list(X,...) | en text med en kommaseparerad lista över de positiva värdena, där "och" skiljer de två sista | |
| mean(X,...) | returnerar medelvärdet av en lista med värden | |
| numAnsOptions(X) | returnerar antalet svarsalternativ som fråga X har | |
| orlist(X,...) | en text med en kommaseparerad lista över de positiva värdena, där "eller" skiljer de två sista | |
| parseDate(X,PAT) | returnerar datumvärdet av texten X tolkad med Javas datumformatmönster PAT | |
| parseNumber(X,PAT) | returnerar det numeriska värdet av texten X tolkad med Javas talformatmönster PAT | |
| showAllResponsesExcept( questionList,attributeList,attributeTitleList) | questionList = lista med frågeidentifierare avgränsade med lodrät streck; attributeList = lista med attribut avgränsade med lodrät streck (som question#, title, text, type - så att du kan bestämma vad som ska visas); attributeTitleList = lista med tabellrubriker avgränsade med lodrät streck, så att rapporten kan internationaliseras. | |
| showTheseResponses( questionList,attributeList,attributeTitleList) | questionList = lista med frågeidentifierare avgränsade med lodrät streck; attributeList = lista med attribut avgränsade med lodrät streck (som question#, title, text, type - så att du kan bestämma vad som ska visas); attributeTitleList = lista med tabellrubriker avgränsade med lodrät streck, så att rapporten kan internationaliseras. |
Expression Manager vet vilka variabler som är lokala
För att kunna bygga JavaScript för en sida korrekt behöver Expression Manager veta vilka variabler som sätts på sidan och vilket JavaScript-ID de har (t.ex. för document.getElementById(x)). Den måste också veta vilka variabler som sätts på andra sidor (så att den kan säkerställa att de nödvändiga fälten <input type='hidden' value='x'> finns och är ifyllda).
Kaskaderande villkor
Om någon av variablerna är irrelevant blir hela ekvationen irrelevant (falsk). I följande tabell betyder N/A att en av variablerna inte var relevant
| Operator | Exempel | a | b | Resultat |
|---|---|---|---|---|
| + (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 |
Åsidosätta kaskaderande villkor
Anta att du vill visa en löpande summa av alla relevanta svar. Du kan försöka använda ekvationen {sum(q1,q2,q3,...,qN)}. Internt översätts den dock till LEMif(LEManyNA('q1','q2','q3',...,'qN'),,sum(LEMval('q1'),LEMval('q2'),LEMval('q3'),...,LEMval('qN'))). Om något av värdena q1-qN är irrelevant returnerar ekvationen därför alltid falskt. I det här fallet visar sum() 0 tills alla frågor har besvarats.
För att komma runt detta kan varje variabel få suffixet ".NAOK" (som betyder att Not Applicable är OK). I sådana fall inträffar följande. Anta att du har variabeln q1.NAOK
- q1 läggs inte till i LEManyNA()-satsen
- LEMval('q1') fortsätter att kontrollera om svaret är relevant och returnerar '' om det inte är det (så enskilda irrelevanta svar ignoreras, men de gör inte hela uttrycket ogiltigt).
Lösningen på problemet med den löpande summan är alltså att använda ekvationen sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).
Suffixet .NAOK gör det också möjligt för författare att utforma enkäter som har flera möjliga vägar men som senare går samman i gemensamma vägar. Anta till exempel att deltagare besvarar en enkät på ett sätt som ligger utanför det normala svarsintervallet. Författaren kan då varna deltagarna för att de kanske inte får giltiga resultat och fråga om de verkligen vill fortsätta med enkäten. Om de svarar Ja visas resten av frågorna. Villkoret för "resten av frågorna" skulle kontrollera om de första svaren låg inom det normala intervallet ELLER om deltagaren svarade Ja på den fråga som bara är relevant om de svarade utanför det normala intervallet.
Hur stöder Expression Manager villkorlig mikroanpassning?
Här är ett exempel på mikroanpassning (där Question Type=='expr' betyder en ekvation):
| Frågekod | Relevans | Frågetyp | Fråga |
|---|---|---|---|
| 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} |
Alla dessa frågor kan ligga på en enda sida (t.ex. i samma grupp), och bara de relevanta frågorna visas. Dessutom uppdateras uttrycket sum() i den sista frågan dynamiskt på sidan när du anger barnens åldrar.
Expression Manager tillhandahåller denna funktion genom att omge varje uttryck med ett namngivet <span>-element. Varje gång ett värde ändras beräknas uttrycket som ska visas i det <span>-elementet om och visningen genereras på nytt. Du kan ha dussintals, eller till och med hundratals, sådana anpassade uttryck på samma sida, och sidan visar om alla med en enda skärmuppdatering.
Översikt över hur LimeSurvey 1.91+ motsvaras i Expression Manager
| Gammal funktion | Ny funktion | Kommentarer |
|---|---|---|
| Villkor | Relevans | Du kan använda mycket komplexa villkorsekvationer och få tillgång till ett bredare urval av variabler |
| Utvärderingar | Ekvation | Alla utvärderingspoäng kan omstruktureras till en ekvation. Det säkerställer både att poängen skrivs till databasen och att du kan se dynamiska förändringar av poängvärdet på den aktuella sidan |
| Ersättningar | Expression Manager | Kärnmotorn tar indatasträngen och behandlar allt inom klammerparenteser som ett uttryck - så den hanterar alla historiska ersättningstyper. För att inte förstöra inbäddad JavaScript bearbetar Expression Manager bara innehåll mellan klammerparenteser om (a) det inte finns inledande eller avslutande blanksteg inom klammerparenteserna - t.ex. är {expr} ett uttryck, men { expr}, {expr } och { expr } är inte uttryck. Dessutom bearbetar Expression Manager inte innehåll inom sina egna strängar (t.ex. {list('hi','there {braces}')} genererar "hi there {braces}"). Den ignorerar också escapade klammerparenteser (t.ex. \{this is not an expression\}) |
| Validering | Expression Manager | Planen är att ta de nuvarande frågeattributen för min/max och låta Expression Manager bearbeta dem. På så sätt kan min/max-värdena själva vara uttryck |
Syntaxmarkering
För att underlätta inmatning och validering av uttryck erbjuder EM syntaxmarkering med följande funktioner:
Typer och betydelser av syntaxmarkering
| Färg | Exempel | Betydelse | Verktygstips | Kommentarer |
|---|---|---|---|---|
| beige bakgrund | Sample | hela ekvationen | ingen | Allt inom klammerparenteser som känns igen som en ekvation (t.ex. utan inledande eller avslutande blanksteg) markeras med beige bakgrund för att skilja det från omgivande text |
| fet röd text | Sample | Ett fel | Någon förklaring av felet | Kan vara en okänd variabel eller ett fel i en funktion, ... Enkäten kan sluta fungera helt, men detta visas inte för användare som svarar. |
| blå text | Sample | funktionsnamn | betydelse och tillåten syntax | funktionsnamn, eller sådant som borde vara funktioner eftersom de följs av en inledande parentes, visas i fet blå text. Verktygstips visar betydelse och tillåten syntax för funktionen. |
| grå text | Sample | sträng | ingen | strängar inom enkla och dubbla citattecken visas i grå text |
| cyan text | Sample | variabel som anges på samma sida, | [namn eller SGQA-kod]: fråga; värde; svarslista som visar koder för varje värde | Alla variabler som anges på samma sida som den aktuella frågan visas i cyan text, vilket visar att de kan uppdateras i javascript. Verktygstipset visar namnet, själva frågan och det nuvarande värdet (eller tomt om det inte är angivet). Om frågetypen förväntar sig svar från en uppsättning uppräknade värden visas kopplingen mellan koderna och visningsvärdena. |
| grön text | Sample | variabel som anges på en tidigare sida | [namn eller SGQA-kod]: fråga; värde; svarslista som visar koder för varje värde | Alla variabler som anges på en tidigare sida visas i fet grön text. Verktygstipset visar namnet, själva frågan och det nuvarande värdet (eller tomt om det inte är angivet). Om frågetypen förväntar sig svar från en uppsättning uppräknade värden visas kopplingen mellan koderna och visningsvärdena. |
| fet rosa text | Sample | variabel som anges på en senare sida i allmänhet: tom vid enkätens start, men kan fyllas i via index eller genom att gå bakåt | [namn eller SGQA-kod]: fråga; värde; svarslista som visar koder för varje värde | Alla variabler som anges på en senare sida visas i fet rosa text. Verktygstipset visar namnet, själva frågan och det nuvarande värdet (eller tomt om det inte är angivet). Om frågetypen förväntar sig svar från en uppsättning uppräknade värden visas kopplingen mellan koderna och visningsvärdena. |
| fet brun text | Sample | ett Lime-ersättningsvärde | värdet | Lime-ersättningssträngar (som {TOKEN:xxx}, {PRIVACY_MESSAGE}) visas i fet brun text. |
| röd text | Sample | tilldelningsoperator (=) | varningsmeddelande | Om du använder en tilldelningsoperator (=) visas operatorn i röd text. Det ska hjälpa dig att undvika oavsiktlig omtilldelning av värden när du egentligen ville kontrollera om a == b i stället för att sätta värdet a = b. |
| normal svart text | Sample | skiljetecken | ingen | All annan interpunktion inom uttrycket visas som normal svart text. |
| text i röd ruta | en fet röd linje omger felet | syntaxfel | beskrivning av felet | Alla upptäckta syntaxfel markeras genom att felet omges av en röd ruta. Verktygstipset visar felet. Exempel är obalanserade parenteser, användning av odefinierade funktioner, fel antal argument till funktioner, dåligt uppbyggda uttryck (t.ex. saknade operatorer mellan variabler), försök att tilldela ett nytt värde till en skrivskyddad variabel, försök att tilldela värden till icke-variabler eller användning av syntax som inte stöds. Observera att systemet för att upptäcka syntaxfel kanske bara rapporterar ett fel i ett uttryck även om det finns flera; om några fel upptäcks visas dock minst ett fel. |
Mer att läsa
Exempelenkäter för Expression Manager
Användningsfall och instruktioner
Steg-för-steg-exempel
Statistikfunktioner i Expression Manager
Referens för utvecklare










