0 votes
in SoSci Survey (dt.) by s233742 (225 points)

Liebes SoSci Survey-Team,

ich habe folgendes Ziel:
Wir wollen eine MESM-Studie durchführen und haben 30 Befragungswellen.
Ich möchte alle Antworten auf eine offene Nennung "MP01" (muss nicht jedes mal ausgefüllt werden) als eine Auswahloption in einem späteren Drop-Down "MP09" verwenden.
D.h. Zu Zeitpunkt 1 geben sie Antwort1, zu Zeitpunkt 2 keine Antwort und zu Zeitpunkt 3 geben sie Antwort2. Zu Zeitpunkt 1 und 2 kann dann bei dem Drop-Down nur eine Antwort1 als Option ausgewählt werden, ab Zeitpunkt 3 dann aber auch Antwort2.
Hierzu habe ich mir die folgenden zwei Artikel von euch zu Gemüte geführt (https://www.soscisurvey.de/help/doku.php/de:create:transfer-responses und https://www.soscisurvey.de/help/doku.php/de:create:use-response) und versucht diese zu kombinieren. Außerdem habe ich bei dem Drop-Down Item 30 Platzhalter von %freund0% bis %freund29% eingefügt aber möchte natürlich, dass nur soviele ersetzt werden wie in den bisherigen Befragungswellen offene Antworten bei MP01 von dieser einen Person abgegeben wurden (also maximal bei der letzten Befragungswelle 30 Antworten). Dabei ist folgender Code herausgekommen:

$key = 'FR-'.caseSerial();
$data = array(
    value('MP02_01')
);
dbSet($key, $data);

Und dann wenn ich es einfügen will:

$key = 'FR-'.caseSerial();
$data = dbGet($key);
$items = array();
for ($i=0; $i<=29; $i++) {
  $antwort = $data[$i];
  if (trim($antwort) != '') {
    replace('%freund'.$i.'%', $antwort);
    $items[] = $i;
  }
}
// Folgefrage anzeigen
if (count($items) > 0) {
  question('MP09', $items);
}

Als Fehlermeldung kommt aktuell folgendes: "Fehler im Fragebogen: Trying to access array offset on value of type bool Zeile: 7". Das mit $1 in dem $data[] scheint also nicht so einfach zu funktionieren wie ich mir das vorgestellt habe.
Ist es denn generell möglich mein Vorhaben umzusetzen und wenn ja, hätten Sie einen Tipp wie ich mein Problem lösen könnte?

Vielen Dank und herzliche Grüße

1 Answer

+1 vote
by SoSci Survey (328k points)
selected by s233742
 
Best answer

Als Fehlermeldung kommt aktuell folgendes: "Fehler im Fragebogen: Trying to access array offset on value of type bool

Diese Fehlermeldung will Ihnen sagen, dass $data eine Variable vom Typ Boolean ist. Das passiert dann, wenn dbGet() keinen Eintrag findet, dann liefert es nämlich false zurück.

Sie müssten also nach dem dbGet() erstmal per Filter prüfen, ob ein passender Eintrag gefunden wurde. Und als Tipp zum Testen: Sie können oben in der Debug-Zeile die Variable SERIAL nach Belieben setzen.

Wenn Sie neben der ersten Person weitere ergänzen möchten, dann könnte das so aussehen:

$key = 'FR-'.caseSerial();
// Bisherige Daten lesen
$data = dbGet($key);
// Array eventuell initialisieren
if (!$data) {
  $data = [];
}
// Neuen Namen in der Liste ergänzen
$data[] = value('MP02_02');
// Und speichern
dbSet($key, $data);
by s233742 (225 points)
edited by s233742
Schonmal vielen Dank für die Antwort!
Tatsächlich ist mein Ziel in dem array von einer Person über mehrere Befragungszeitpunkte die Antworten immer auf die Frage 'MP02_01' zu sammeln und diese dann zeitgleich später in dem Fragebogen in einer Folgefrage aufzulisten.
Um es konkreter zu machen: Fragebogen XY wird insgesamt 30 mal abgefragt. Auf Seite 2 kommt die Frage (MP02_01): "Bitte beschrieben Sie in zwei Wörtern das wichtigste Verhalten:" + Textfeld und auf Seite 7 kommt dann ein Drop-Down wo alle bisher beschriebenen Verhaltensweisen dieser Person aufgelistet sind (also bei Befragungszeitpunkt 15 potentiell bis zu 15 Verhaltensweisen aber eventuell auch weniger weil die Frage auf Seite 2 nicht zwingend beantwortet werden muss).
Die Antworten sollen also pro Person separat gespeichert werden aber das wird ja eigentlich über 'caseSerial' sichergestellt.
Hatten Sie das bereits so verstanden?
Und wenn ja an welche Stelle gehört dann der von Ihnen ergänzte Code? Auf die Seite 2, also zum Item 'MP02' oder zum Abruf auf Seite 7?

Der Fehlercode im Debug Modus sieht wie folgt aus:

Im PHP-Code trat ein Fehler auf.
Fehler im Fragebogen: Undefined array key 1
Zeile: 7

PHP-Code

004 $data = dbGet($key);
005 $items = array();
006 for ($i=0; $i<=29; $i++) {
007   $antwort = $data[$i];      (007 ist rot markiert)
008   if (trim($antwort) != '') {
009     replace('%freund'.$i.'%', $antwort);
010     $items[] = $i;

Diese Fehlermeldung wird bis zum Platzhalter 29 angezeigt.
Außerdem wird die folgende Warnung für alle 30 Platzhalter angezeigt:

Für den Platzhalter %freund0% wurde weder ein Eingabefeld mit prepare_input() vorbereitet, noch ein Inhalt mit replace() festgelegt.
by SoSci Survey (328k points)
> Hatten Sie das bereits so verstanden?

Ja. Bis auf die konstante Variable. Sie sollten zur Sicherheit noch dafür sorgen, dass derselbe Name nicht zweimal im Array landet.

$data[] = value('MP02_01');
$data = array_unique($data);

> Fehler im Fragebogen: Undefined array key 1

Das liegt daran, dass Ihre FOR-Schleife immer 30 Einträge durchgehen will, auch wenn erst ein Name in der Liste steht. Besser:

foreach ($data as $i => $antwort) {
  if (trim($antwort) != '') {
    replace('%freund'.$i.'%', $antwort);
    $items[] = $i;
  }
}

> Für den Platzhalter %freund0% wurde weder ein Eingabefeld mit
> prepare_input() vorbereitet, noch ein Inhalt mit replace() festgelegt.

Das sollte nicht mehr passieren, wenn die Frage nur noch die Items anzeigt, zu denen auch ein Name vorliegt. Kümmern wir uns um dieses Problem später, wenn es noch auftritt.
by s233742 (225 points)
Klasse vielen Dank! Die Fehlermeldung konnten wir somit schonmal beheben!

Die Warnungen werden leider noch immer angezeigt. Außerdem werden auch noch alle Platzhalter angezeigt.

Hier der Code wie er aktuell aussieht: (nicht dass wir aneinander vorbei reden :) )

$key = 'FR-'.caseSerial();
$data = dbGet($key);
$items = array();

foreach ($data as $i =>$antwort) {
  if (trim($antwort) != '') {
    replace('%freund'.$i.'%', $antwort);
    $items[] = $i;
  }
}

Kann es sein, dass man "$antwort" erst noch definieren muss?

Nochmals vielen Dank für Ihre Unterstützung!
by SoSci Survey (328k points)
> Kann es sein, dass man "$antwort" erst noch definieren muss?

Das macht die foreach()-Schleife.

> Die Warnungen werden leider noch immer angezeigt.

Sie haben im PHP-Code keinen question()-Befehl. Das heißt, Sie nutzen die Variable $items wohl noch nicht.

Binden Sie die Folgefrage mit den Platzhaltern nun bitte wie folgt ein:

question('AB01', $items);
by s233742 (225 points)
Also so sieht jetzt der gesamte Code aus:

$key = 'FR-'.caseSerial();
$data = dbGet($key);
$items = array();

foreach ($data as $i => $antwort) {
  if (trim($antwort) != '') {
    replace('%freund'.$i.'%', $antwort);
    $items[] = $i;
  }
}

question('MP09', $items);

Die Warnungen werden weiterhin angezeigt.
Nur dass es nicht am Drumherum scheitert. Ich habe den PHP-Code im Fragebogen vor der Folgefrage MP09 aber beide Bausteine (also Code und Folgefrage) auf der gleichen Seite. Und die Warnung erscheint unabhängig davon ob ich die Variable SERIAL im Debug Modus definiere oder nicht.
Haben Sie noch eine Idee was man noch versuchen könnte?
Oder kann ich Ihnen irgendwie Zugriff zu meinem Projekt gewähren, damit sie sich ein Bild von der Lage machen können, ob mir an anderer Stelle ein Fehler unterlaufen ist?
by SoSci Survey (328k points)
> vor der Folgefrage MP09 aber beide Bausteine (also Code und Folgefrage) auf der gleichen Seite.

Die MP09 darf nur mittels question() eingebunden werden, wenn Sie sie zusätzlich noch in die Seite gezogen haben, entfernen Sie diese bitte.
by s233742 (225 points)
edited by s233742
Alles klar!
Das habe ich so gemacht, jetzt wird mir die Frage einfach nicht mehr angezeigt.
Kann das daran liegen, dass ich jetzt erst zu einem zweiten Befragungszeitpunkt sehe ob es funktioniert?
Oder sollte mir da zumindest schonmal die Antwort angezeigt werden, die ich zu diesem Zeitpunkt früher im Fragebogen eingetragen habe?

Und vielleicht der Vollständigkeit halber hier nochmal mein gesamter Code von der Abspeicherung, nicht dass es am Ende an dem liegt:

$key = 'FR-'.caseSerial();
$data[] = value('MP02_01');
$data = array_unique($data);
dbSet($key, $data);

Und den habe ich nach der Frage MP02 (deren Antworten ich später einfügen will) auf die gleiche Seite gesetzt.
by SoSci Survey (328k points)
> Kann das daran liegen, dass ich jetzt erst zu einem zweiten Befragungszeitpunkt sehe ob es funktioniert?

Solange keine Namen in der Datenbank vorliegen (für den Teilnehmer), bleibt die Liste der $items leer, und die Frage wird nicht angezeigt. Korrekt.

Lassen Sie sich doch einfach ausgeben, was SoSci Survey da abruft (am Ende des Codes):

debug($key);
debug($data);
debug($items);
by s233742 (225 points)
Vielen Dank!
Also dann werde folgende Informationen angezeigt:

Debug-Information für $key:
$key = FR-22 (string)

Debug-Information für $data:
0

Debug-Information für $items:
Array (ohne Elemente)

Sollten das die Antworten sein? (für SERIAL hatte ich 22 angegeben, das scheint also schonmal zu funktionieren :) )

Und vielleicht der Vollständigkeit halber hier nochmal mein gesamter Code von der Abspeicherung, nicht dass es am Ende an dem liegt:

$key = 'FR-'.caseSerial();
$data[] = value('MP02_01');
$data = array_unique($data);
dbSet($key, $data);

Und den habe ich nach der Frage MP02 (deren Antworten ich später einfügen will) auf die gleiche Seite gesetzt.
by SoSci Survey (328k points)
> Sollten das die Antworten sein?

Ja, wenn in der Datenban für Inhalte bereits Namen gespeichert wären, würde diese hier auftauchen.

> Und den habe ich nach der Frage MP02 (deren Antworten ich später einfügen will) auf die gleiche Seite gesetzt.

Das wird nicht funktionieren, vgl. "Wichtig" auf https://www.soscisurvey.de/help/doku.php/de:create:functions:value und https://www.soscisurvey.de/help/doku.php/de:create:filter-solving#top_1
by s233742 (225 points)
Merci!
Wir kommen der Sache gefühlt näher.

Jetzt werden Inhalte angezeigt (was ja schonmal ein gutes Zeichen ist, d.h. das mit dem Abspeichern scheint zu funktionieren!) aber es wird auch die folgende Warnung angezeigt:

Warnung (Seite 8)
Für die Frage MP09 wurde kein Item mit der Kennung 0 gefunden

Debug-Information für $key:
$key = FR-1 (string)

Debug-Information für $data:
0Test

Debug-Information für $items:
00

Eigentlich soll ja das Item %freund0% zuerst angezeigt werden, dies hat aber die Kennung 01 (da die Kennung 00 ja nicht existiert).

Wenn man also einfach die Zeile mit der Variable $items wie folgt ergänzt wird die Folgefrage korrekt angezeigt:
 $items[] = $i +1;

Hier nochmal der gesamte Code falls jemand in Zukunft auf die Idee kommen sollten, ein ähnliches Spektakel veranstalten zu wollen:

Auf Seite x (z.B. Seite 2) steht die Frage (in diesem Fall MP02), deren Antworten man verwenden möchte.
Auf Seite x + 1 (im Bsp. Seite 3) steht folgender PHP-Code:
$key = 'FR-'.caseSerial();
$data[] = value('MP02_01');
$data = array_unique($data);
dbSet($key, $data);

Auf Seite x+y (z.B. Seite 7) soll die Folgefrage (MP09) erscheinen, die die Antworten beinhalten soll und dort steht der folgende PHP-Code:
$key = 'FR-'.caseSerial();
$data = dbGet($key);
$items = array();

foreach ($data as $i => $antwort) {
  if (trim($antwort) != '') {
    replace('%freund'.$i.'%', $antwort);
    $items[] = $i + 1;
  }
}

question('MP09', $items);

(%freund0% ist die Bezeichnung für den ersten Platzhalter in der Folgefrage; die Zahl wird durch die Variable "i" in dem Code berücksichtigt.)

Sehr geehrtes Support-Team vielen herzlichen Dank für Ihre Geduld und ausdauernde Hilfestellung. Ich habe die Hoffnung, dass es jetzt funktioniert!
by SoSci Survey (328k points)
> Für die Frage MP09 wurde kein Item mit der Kennung 0 gefunden

Ja, guter Punkt. Das Array $data ist ab 0 nummeriert, die Items ab 1. Also ist Ihre Lösung aus meiner Sicht vollkommen korrekt. Vorausgesetzt, in Item 1 steht der Platzhalter %freund0%.

Danke, dass Sie den vollstängen Code nochmal gepostet haben.
by s233742 (225 points)
Hallo,
es geht leider doch nochmal weiter. Ich habe die Funktion jetzt auch mal im Serienmail-Betrieb getestet und musst leider feststellen, dass nicht die Liste aller bisher gegebenen Antworten angezeigt wird, sondern immer nur die letzte Antwort.
Hier nochmal der Code, ich habe noch ein zwei Zeilen abgeändert:
$key = 'FR-'.caseSerial();
$data = dbGet($key);
$items = array();
$items[] = 31;   (diese Zeile habe ich eingefügt, damit immer das "Sonstige"-Item angezeigt wird)

if (!empty($data)) {       (Diese Zeile habe eingefügt weil es zu einem Fehler kam, wenn noch keine Antwort gegeben wurde und $data somit leer war)
    foreach ($data as $i => $antwort) {
        if (trim($antwort) != '') {
            replace('%freund'.$i.'%', $antwort);
            $items[] = $i + 1;
        }
    }
}


question('MP09', $items);

Haben Sie eine Idee wie man dieses Problem lösen könnte?
by SoSci Survey (328k points)
Finden wir erst einmal heraus, an welcher Stelle es hakt: Funktioniert es denn mit dem Speichern - also, wenn Sie in der Datenbank für Inhalte nachsehen, sind da alle Namen sichtbar?
by s233742 (225 points)
edited by s233742
Vermutlich hakt es bereits dort: In der Datenbank für Inhalte ist pro Schlüssel nur ein Eintrag (jeweils der letzte). Hat das seine Richtigkeit?
Ich dachte, pro Person bzw. caseSerial wird ein Array angelegt, wo dann die Eingabe aus jedem neuen Fragebogen zusätzlich eingetragen wird. Aber das scheint ja nicht der Fall zu sein oder?
Lässt sich das trotzdem umsetzen?
by SoSci Survey (328k points)
> Hat das seine Richtigkeit?

Nein ;)

Welche Code verwenden Sie aktuell genau zum Speichern der Namen?
by s233742 (225 points)
Na dann besteht ja Hoffnung :)
Den hier:

$key = 'FR-'.caseSerial();
$data[] = value('MP02_01');
$data = array_unique($data);
dbSet($key, $data);
by SoSci Survey (328k points)
Da fehlt das Auslesen der vorigen Antworten, die Sie ja behalten (und nicht einfach überschreiben) möchten. Ich hatte es oben in meiner Antwort wie folgt geschrieben:

$key = 'FR-'.caseSerial();
// Bisherige Daten lesen
$data = dbGet($key);
// Array eventuell initialisieren
if (!$data) {
  $data = [];
}
// Neuen Namen in der Liste ergänzen
$data[] = value('MP02_01');
// Und speichern
dbSet($key, $data);
by s233742 (225 points)
Oh das war mir durch die Lappen gegangen.
Damit funktioniert es jetzt komplett!
Nochmals vielen herzlichen Dank :)

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...