====== Datenbank für Inhalte ====== In den **Spezialfunktionen** findet sich eine **Datenbank für Inhalte**. Dies ist eine projektinterne Miniatur-Datenbank (nicht-relational), in der Daten für die Verwendung im Fragebogen abgelegt oder sogar während des Interviews geändert werden können. Das führt zu vielfältigen Möglichkeiten, z.B. * Eine größere Anzahl von Textfragmenten effizient verwalten * Werte an nachfolgende Interviews übergeben * Daten über mehrere Interviews hinweg verwalten (z.B. Quoten zählen, Stimuli systematisch rotieren) bzw. Daten zwischen Interviews austauschen * Anhand des Personenkennung, dem Teilnahmecode oder der Referenz personalisierte Daten einblenden (Daten im Interview zuspielen) * Eingabefelder im Fragebogen individuell vorbelegen (in Kombination mit ''[[:de:create:functions:preset|preset()]]'') Die Fragetypen [[:de:create:questions:extselect|Erweiterte Auswahl]] und [[:de:create:questions:suggest|Texteingabe mit Auswahlempfehlung]] bieten darüber hinaus die Möglichkeit, auf die Datenbank zuzugreifen. So lassen sich sehr umfangreiche und/oder dynamische Auswahlfragen programmieren. Um mittels PHP-Code auf die Datenbank zuzugreifen, dienen die Befehle ''[[:de:create:functions:dbget|dbGet()]]'' und ''[[:de:create:functions:dbset|dbSet()]]''. Mit dem Befehl ''dbGet()'' werden die Daten zu einem Schlüssel ausgelesen, mit ''dbSet()'' können Daten in die Datenbank geschrieben werden. Mit dem Befehl ''[[:de:create:functions:dbkeys|dbKeys()]]'' lassen sich die verfügbaren Schlüssel auflisten. **Wichtig:** Bitte beachten Sie, dass die Daten in der **Datenbank für Inhalte** beim Export des Projekts noch __nicht__ exportiert werden. Beim Archivieren eines Projekts werden die Daten nicht archiviert, sondern gelöscht. Eine Änderung dieses Verhaltens ist in kommenden Programmversionen angedacht. ===== Funktion ===== In der **Datenbank für Inhalte** können Paare aus jeweils einem Schlüssel (eine Kennung) und Daten hinterlegt werden. * Der //Schlüssel// kann eine Zahl oder ein kurzer Text (max. 64 Zeichen) sein. * Wenn man Schlüssel für unterschiedliche Kategorien benötigt, kann man dem Zahlencode einfach einen Buchstaben voranstellen, z.B. A1, A2 und A3 für Kategorie 1 sowie B2, B2, B3 und B4 für Kategorie 2. * Der Schlüssel darf zu Beginn und am Ende keine Leerzeichen enthalten (diese werden abgeschnitten). Steuerzeichen (Tabulator o.ä.) werden entfernt. Leerzeichen und Sonderzeichen sind hingegen erlaubt. * Die //Daten// sind jeweils Kombinationen (Arrays) aus einer oder mehreren Texten und/oder Zahlen. Zahlen werden wie Texte behandelt und liegen später im Fragebogen als Text vor (z.B. ''%%'1'%%''). Steuerzeichen (z.B. Zeilenumbrüche) sind in den Texten nicht möglich -- HTML-Tags selbstverständlich schon. Im Fragebogen kann man dann anhand des Schlüssels die hinterlegten Daten abrufen. Bildlich dargestellt könnte eine Datenbank folgende Paare aus Schlüsseln und Daten enthalten: ^Schlüssel^Daten (Kombinationen)^ |A1|(Apfelbaum, Äpfel)| |A2|(Birnbaum, Birnen)| |A3|(Clementinenbaum, Clementinen)| |B1|(6)| |B2|(12)| |B3|(18)| |B4|(24)| |B5|(30)| ===== Daten einlesen ===== Die Daten müssen zunächst in einer Tabelle vorliegen, z.B. in Excel oder OpenOffice Calc: * Dabei muss die erste Spalte den Schlüssel enthalten, * die weiteren Spalten enthalten die Daten. * In der ersten Zeile dürften keine Überschriften stehen, die Tabelle muss sofort mit Daten beginnen. Um die oben dargestellten Datenbankeinträge zu erzeugen, würde Ihre Tabelle aussehen wie folgt: |A1|Apfelbaum|Äpfel| |A2|Birnbaum|Birnen| |A3|Clementinenbaum|Clementinen| |B1|6| | |B2|12| | |B3|18| | |B4|24| | |B5|30| | Diese Tabelle speichern Sie im Dateiformat XLSX (Excel) oder CSV (Character Separated Values) ab. CSV-Dateien sind Textdateien, in der die Werte hintereinander stehen und durch ein vorgegebenes Zeichen (z.B. einen Tabulator) getrennt sind. Wählen Sie unter **Spezialfunktionen** -> **Datenbank für Inhalte** nun bei //Daten einlesen// die Tabelle aus und bestätigen mit //OK//. Im folgenden Fenster werden noch ein paar Details abgefragt -- normalerweise erkennt SoSci Survey die korrekten Format-Einstellungen der Datei automatisch. **Hinweis:** Jede Zeile in der Tabelle muss mindestens 2 Spalten haben. Zeilen, die nur einen Schlüssel oder gar keine Daten enthalten, werden beim Import ignoriert. ==== Daten mit Sprachversion einlesen ==== Wenn Sie in einem mehrsprachigen Projekt arbeiten, können Sie für unterschiedliche Sprachversionen unterschiedliche Daten hinterlegen. Das Programm prüft beim Abruf eines Datenbank-Eintrags, ob für die aktuelle Sprachversion ein eigener Eintrag vorliegt -- und wenn nicht, wird der Eintrag aus der Basissprache verwendet ([[multilang|Mehrsprachige Befragungen]]). Sie können in der Import-Datei festlegen, für welche Sprache ein Eintrag gedacht ist. Erstellen Sie dazu eine Spalte mit dem Namen ''LANGUAGE''. ^KEY^LANGUAGE^D0 ^D1 ^ |A1 | ger |Apfelbaum |Äpfel | |A1 | eng |apple tree |apples | |A2 | ger |Birnbaum |Birnen | |A2 | eng |pear tree |pears | |A3 | ger |Clementinenbaum|Clementinen| |A3 | eng |Clementine tree|clementines| ==== JSON-Daten einlesen ==== Die Datenbank für Inhalte kann auch JSON-Objekte speichern. Diese können nicht über ''[[:de:create:functions:dbget]]'' sondern nur über ''[[:de:create:functions:dbretrieve]]'' abgerufen werden. Anders als "normale" Datenbankeinträge können hier auch keine unterschiedlichen Sprachversionen hinterlegt werden. Geben Sie als ''LANGUAGE'' den Code "qcb" ein, um JSON-Objekte als solche zu importieren. Für JSON-Einträge ist nur eine Spalte erlaubt. ^KEY^LANGUAGE^D0 ^ |A1 | qcb |''%%{tree:"Apfelbaum", fruit:"Äpfel"}%%''| |A2 | qcb |''%%{tree:"Birnbaum", fruit:"Birnen"}%%''| |A3 | qcb |''%%{tree:"Clementinenbaum", fruit:"Clementinen"}%%''| ===== Daten ändern ===== Sofern Sie die Daten ändern möchten, importieren Sie eine neue/weitere CSV-Datei. Doppelte Schlüssel werden dabei aktualisiert (überschrieben). Ansonsten werden bestehende Schlüssel nicht verändert. Um Einträge zu löschen, können Sie im Karteireiter "Einträge Löschen" entweder einzelne Einträge entfernen oder die gesamte Datenbank (alle Einträge) löschen. Mit der Funktion ''[[:de:create:functions:dbset|dbSet()]]'' können Einträge in der **Datenbank für Inhalte** auch während des Interviews geändert oder gelöscht werden. ===== Daten herunterladen ===== Falls die Daten während der Erhebung mittels ''[[:de:create:functions:dbset]]'' aktualisiert wurden, kann man den Inhalt der "Datenbank für Inhalte" jederzeit als CSV-Datei herunterladen: **Spezialfunktionen** -> **Datenbank für Inhalte** -> Knopf "Herunterladen" ===== Anwendungsbeispiele ===== ==== Umfangreiches Testmaterial ==== In einer Studie sollen 500 Zeitungsartikel von unterschiedlichen Personen beurteilt werden. Die Artikel entstammen einer elektronischen Datenbank und liegen bereits in tabellarischer Form vor. Damit jeder Artikel gleich häufig beurteilt wird, kommt eine [[:de:create:random_urns|Randomisierung mit Urnen]] zum Einsatz. Aber es wäre denkbar ineffizient, 500 Textbausteine einzeln anzulegen. Zunächst müssen die Artikel in die projektinterne Datenbank importiert werden. Dazu wird in einer Tabellenkalkulation eine Tabelle mit den 500 Artikeln wie folgt angelegt: ^Schlüssel^Titel^Text^ |a1|Streik der Lokführer: Gesellschaft als Geisel|Das Streikrecht ist aus guten Gründen in der Verfassung ...| |a2|Die Funktion von Junckers Netzwerk|EU-Kommissionschef Juncker pflegt Beziehungen mit Europas Führungskräften...| |a3|Carsten Maschmeyer verklagt Schweizer Bank|Der Investor Carsten Maschmeyer hat nach Informationen der Süddeutschen ...| Die Tabelle wird als CSV-Datei gespeichert. Die erste Zeile dient hier nur der Beschriftung -- der der CSV-Datei sollte sie nicht enthalten sein. Unter **Spezialfunktionen** -> **Datenbank für Inhalte** wird die CSV-Datei in das Projekt importiert. In der Urne "artikel" liegen die Zahlen 1 bis 500 (jeweils eine Zahl pro Zeile). Details zur Urnenziehung s. [[:de:create:random_urns|Randomisierung mit Urnen]]. Im Fragebogen wird ein Zettel aus der Urne entnommen, mittels ''dbGet()'' der Eintrag aus der Datenbank ausgelesen und anschließend via ''html()'' der Artikel angezeigt: urnDraw('artikel', 'IV01'); $key = 'a'.value('IV01_01'); // Ein "a" vor die Zahl schreiben $inhalt = dbGet($key); html('

'.$inhalt[0].'

'.$inhalt[1].'
');
==== Daten zwischen Interviews austauschen ==== In der Vorerhebung einer Tagebuchstudie wird abgefragt, welche Fernsehsender eine Person nutzt. In den weiteren Erhebungen der Tagebuchstudie wird die tägliche Nutzungsdauer für die jeweiligen Sender abgefragt. Dazu sollen in einer offenen Texteingabe nur jene Sender angeboten werden, die in der Vorerhebung ausgewählt wurden. Für die gesamte Tagebuchstudie kommt die Serienmail-Funktion von SoSci Survey zum Einsatz. Über ''caseSerial()'' kann daher in jedem Fragebogen ein eindeutiger Personen-Code ermittelt werden. **Hinweis:** Falls die E-Mail-Adresse im ersten Fragebogen erst erhoben wird ([[:de:survey:opt-in-live]]), verwenden Sie in diesem Fragebogen statt ''caseSerial()'' bitte ''value()'' mit der Kennung der Opt-In-Frage. In der Vorerhebung werden die genutzten Fernsehsender mit der Mehrfachauswahl "FS01" auf Seite 2 des Fragebogens abgefragt. Auf Seite 3 (oder später) wird die Auswahl in der Datenbank vermerkt: $sender = getItems('FS01', 'is', 2); $key = 'FS-'.caseSerial(); // Dem Teilnahmecode wird noch ein "FS-" vorangestellt, damit in der Datenbank auch noch andere Inhalte gespeichert werden können. dbSet($key, $sender); In den täglichen Fragebögen wird die Nutzungsdauer für die Sender mittels offener Texteingabe "NU03" abgefragt. Diese Frage enthält dieselben Items wie Mehrfachauswahl "FS01" in derselben Reihenfolge. Folgender PHP-Code liest die Daten aus der Datenbank und zeigt nur die entsprechenden Eingabefelder an: $key = 'FS-'.caseSerial(); $sender = dbGet($key); question('NU03', $sender); **Wichtig:** ''dbGet()'' liefert immer ein Array -- auch wenn man mit ''dbSet()'' nur einen einzelnen Wert speichert. Wenn man im ersten Fragebogen einen einzelnen Wert speichert, muss man im anderen Fragebogen mittels eckiger Klammer (''[0]'') auf das erste (und einzige) Array-Element zugreifen. $group = value('RG01'); $key = 'RG-'.caseSerial(); // Auch hier wird ein Präfix für den Datenbank-Eintrag verwendet, um alle Optionen offen zu halten dbSet($key, $group); $key = 'RG-'.caseSerial(); $data = dbGet($key); if ($data) { $group = $data[0]; // Zwischenspeichern des Werts in eine interne Variable, // um den Wert später via value() zu verwenden (optional) put('IV01_01', $group); } else { // Fehlermeldung anzeigen, dass etwas schief gelaufen ist show('XY01'); put('IV01_01', -1); } Der PHP-Code für den zweiten Fragebogen sieht auch den Fall vor, dass in der Datenbank für Inhalte kein passender Eintrag gefunden wird. Das könnte z.B. passieren, wenn die Befragte den ersten Fragebogen nicht bis zum ''dbSet()'' ausgefüllt hat. ==== Auswertung zuspielen ==== In einer Befragung müssen die Teilnehmer mehrere lange Skalen ausfüllen. Als Dankeschön können Sie 2 Wochen später eine Auswertung ihrer Ergebnisse einsehen. Die Auswertung kann nicht live erfolgen (''[[:de:create:functions:valuemean|valueMean()]]'', [[:de:create:points|Punkte für Antworten zählen]]), weil zunächst die Normwerte aus der Stichprobe bestimmt werden müssen. Zum Abruf ihrer Ergebnisse müssen die Teilnehmer einen Code notieren, weil die Erhebung anonym erfolgt. Im ersten Fragebogen wird also lediglich ein 8-stelliger Zufallscode erstellt, im Datensatz gespeichert und angezeigt: $chars = 'ABCDEFHKLMNPRSTUVWXYZ23456789'; // Zeichen, die man i.d.R. nicht verwechseln kann $code = ''; for ($i=0; $i<8; $i++) { $code.= $chars[mt_rand(0, strlen($chars)-1)]; } // Code im Datensatz speichern (mit vorangestelltem "X-") put('IV02_01', 'X-'.$code); // Code anzeigen html('

Ergebnisse

Bitte notieren Sie '.$code.'

');
Die Daten werden nach der Erhebung ausgewertet und für jeden Teilnehmer werden drei Ergebnis-Werte berechnet. Diese werden -- zusammen mit dem Code aus IV02_01 -- in einer Tabelle und als CSV-Datei gespeichert: |X-ABCDEF12|7|19|8| |X-CDEFG234|24|16|19| |X-ZU7652AB|15|95|80| Im zweiten Fragebogen müssen die Teilnehmer zunächst ihren Code eingeben (offene Texteingabe "AB01_01"). Auf der zweiten Seite wird dann geprüft, ob der Code in der Datenbank vorhanden ist und wenn ja, dann werden die Ergebnisse angezeigt. $key = 'X-'.value('AB01_01'); // Auch hier wird wieder das X vorangestellt $result = dbGet($key); // Bei falschem Code, die Code-Abfrage (vorige Seite) nochmal anzeigen if ($result === false) { text('wrong code'); repeatPage(); } // Ansonsten wird das Ergebnis angezeigt html('

Ausgeschlafenheit: '.$result[0].'%

Schlauheit: '.$result[1].'%

Gemütlichkeit: '.$result[2].'%

');
==== Daten a-priori zuspielen ==== In einer (nicht-anonymen) Kundenbefragung sind einige Stammdaten bereits bekannt -- sie sollen im Fragebogen aber aktualisiert/vervollständigt werden. Die Kunden erhalten personalisierte Links (Zugriff "Teilnahmecode") mit einem Code, der jedem Kunden vorab zugeteilt wurde. Hierfür werden 12-stellige Zufallscodes verwendet, damit man nicht einfach die Codes anderer Kunden erraten und deren Daten abrufen kann, wie es bei einer fortlaufenden Kundennummer leicht möglich wäre. Es wird eine Tabelle erstellt, die als erste Spalte den Code enthält und daneben die Stammdaten. Die Tabelle wird als CSV-Datei gespeichert und in die projektinterne Datenbank importiert. |12345678ABCD|SoSci Survey GmbH|Marianne-Brandt-Str.|29|80807|München| |9876542UBGAD|Musterfirma AG|Musterweg|7|12345|Musterstadt| |72KU635485UG|MSD-Media GbR|Korbinianstr.|17||| Der Code wird im personalisierten [[:de:survey:url|Link zum Fragebogen]] als Teilnahmecode (''s'') übergeben und steht im PHP-Code daher via ''caseSerial()'' zur Verfügung. Die offene Texteingabe "ST01" hat folgende Eingabefelder: Firma (01), Straße (02), Hausnummer (03), PLZ (04), Ort (05). Mittels ''prepare()'' werden nun die bekannten Daten eingetragen -- der Kunde kann sie beim Ausfüllen ggf. anpassen. $key = caseSerial(); $info = dbGet($key); if ($info !== false) { preset('ST01_01', $info[0]); preset('ST01_02', $info[1]); preset('ST01_03', $info[2]); preset('ST01_04', $info[3]); preset('ST01_05', $info[4]); } // Jetzt noch die Frage anzeigen question('ST01'); ==== Daten ergänzen ==== Um während des Interviews einen Eintrag in der Datenbank für Inhalte zu ergänzen, muss dieser ausgelesen, ergänzt und dann wieder geschrieben werden. Zum Beispiel wurden unter dem Schlüssel "FS-" a-priori Daten hinterlegt (3 Einträge pro Person, also Indizes 0 bis 2). In Befragungswelle 1 soll nun eine Produktpräferenz aus Frage PP01 als viertes Datum (Index 3) ergänzt werden. Der folgende PHP-Code könnte dann auf der Seite __nach__ der Seite mit PP01 stehen (s. Hinweise zu ''[[:de:create:functions:value]]''). $key = 'FS-'.caseSerial(); // Daten auslesen $data = dbGet($key); if ($data === false) { // Keine Daten gefunden - vielleicht eine Warnung anzeigen $data = array(-8, -8, -8); // ... und das Datenelement initialisieren } // Die Antwort aus PP01 ergänzen $data[3] = value('PP01'); // Eintrag erneut speichern $data = dbSet($key, $data); ==== Auswahloptionen sukzessive einschränken ==== Die Datenbank für Inhalte kann auch dafür verwendet werden, um lange Auswahllisten schrittweise einzuschränken. Im folgenden Beispiel soll zunächst ein Stadtteil ausgewählt werden und dann im nächsten Schritt eine Haltstelle innerhalb des Stadtteils. Dafür wird in der Datenbank für Inhalte zunächst eine Liste angelegt, welche die Stadtteile beinhaltet und die Haltestellen. Wichtig ist die Vergabe geeigneter Datenbankschlüssel. Diese müssen folgende Kriterien erfüllen: - Stadtteile und Haltestellen benötigen ein unterschiedliches Präfix, das heißt, die Schlüssel müssen z.B. mit unterschiedlichen Buchstaben beginnen. Im Beispiel beginnen die Schlüssel für Stadtteile mit "S" und jene für die Haltestellen mit "H". - Die Haltestellen, welche zu einem Stadtteil gehören, müssen nach dem "H" denselben weiteren Code verwenden. Alle Haltestellen in Stadtteil A würden also z.B. mit "H01" beginnen. - Es spart Arbeit, wenn man den Antwortcode für die Stadtteile so wählt, dass sie mit den Präfixen der Haltestellen-Schlüssel übereinstimmen. Also z.B. Code 1 für Stadtteil A und entsprechend die Präfixe "H01" für die zugehörigen Haltestellen. Die Liste für den Import könnte also wie folgt aussehen: S01 1 Stadtteil A S02 2 Stadtteil B S03 3 Stadtteil C ... S50 50 Stadtteil Zeta H0101 101 Haltestelle "Ammersberg" in Stadtteil A H0102 102 Haltestelle "Breitenbach" in Stadtteil A H0103 103 Haltestelle "Clemensstraße" in Stadtteil A ... H5017 5015 Haltestelle "Zwiebelturm" in Stadtteil Zeta Nun werden im Fragenkatalog zwei Fragen vom Typ [[:de:create:questions:extselect]] erstellt. Die Optionen sollen diese beiden Fragen [[:de:create:questions:extselect#optionen_aus_der_datenbank|aus der Datenbank beziehen]]. Als Präfix in der Frage für die Stadtteile stellen Sie "S" ein und als Datenbank-Präfix für die Haltestellen-Frage ein "H". Die Vorschau zeigt nun zunächst alle Haltestellen. **Tipp:** Anstatt einer erweiterten Auswahl können Sie auch eine [[:de:create:questions:suggest]] verwenden. Das ist dann sinvoll, wenn Sie z.B. bei den Stadtteilen sehr viele Antwortoptionen haben. Wenn die Vorschau der Fragen Ihren Wünschen entspricht (nur bei den Haltestellen eben noch zu viele anzeigt), dann geht es nun and **Fragebogen zusammenstellen**. Dort platzieren Sie die Fragen nach den Stadteilen ("AF01" im Beispiel) auf eine Seite. Auf der nächsten Seite wird dann mit ein wenig PHP-Code und der Funktion ''[[:de:create:functions:question]]'' die Frage für die Haltestellen ("AF02") platziert. Und zwar wird hier mit dem Parameter ''%%'filter'%%'' sichergestellt, dass nur die passenden Haltestellen angezeigt werden. // Erst einmal den ausgewählten Stadtteil auslesen $stadtteil = value('AF01'); // Dann das Präfix für die passenden Haltestellen erstellen $prefix = 'H'.sprintf('%02d', $stadtteil); // Dann die Frage nach dem Stadtteil mit den passenden Optionen zeigen. question('AF02', 'filter='.$prefix); Die Funktion ''sprintf()'' sorgt dafür, dass der Antwortcode aus AF01 zweistellig (Formatcode ''%02d'') ausgegeben wird aus ''1'' wird dadurch der String ''%%'01'%%''. Der Punkt (''.'') dient in PHP dazu, Strings zu verketten. Wenn in der Variable ''$prefix'' also z.B. "H01" gespeichert ist, dann wird aus ''%%'filter='.$prefix%%'' ein ''%%'filter=H01'%%''.