Aus gegebenem Anlass dachte ich mir: ich schreibe mal ein ganz kurzes HowTo zur Fehlersuche in einer Formel. Leider gibt es ja hier (seit R6) keinen Debugger mehr, so dass man sich selbst behelfen muss.
Wie geht man also vor, wenn einem eine Formel einfach ein "Falscher Datentyp @Funktion: Zeit/Datum erwartet" oder ähnliches hinrotzt, und man keine Ahnung hat, was los ist:
Grundsätzlich muss man die Formel in kleinste Teile aufsplitten und die Ergebnisse dieser "Teile" zurückliefern so lange, bis man rausfindet, woran es liegt.
Nehmen wir als Beispiel diese Formel aus einem aktuellen Thread:
_range := @Explode( @Texttotime( "[" + @Text( co_Start ) + " - " + @Text( co_End ) + "]" ) );
@Unique( @Month( _range ) )
Nun geht man von innen nach außen und weist einzelnen Elementen eigene Variablen zu. Hier ist der "innerste" Befehl @Text( co_start ) bzw. @Text( co_End ).
Weisen wir diesen also mal Variablen zu, und liefern am Ende eine dieser Variablen zurück. Dabei machen wir uns die Tatsache zu nutze, dass die Formel- Sprache immer den LETZTEN Rückgabewert zurückliefert und alle vorherigen "vergisst":
_start := @Text( co_Start );
_end := @Text( co_End );
_range := @Explode( @Texttotime( "[" + _start + " - " + _end + "]" ) );
@Unique( @Month( _range ) );
REM "Obwohl wir den "unique" schon zurückliefern überschreiben wir hier den Rückgabewert einfach mit was anderem";
_start
Sieht das OK aus? - wenn ja, dann das ganze mit _end wiederholen. Wenn das immer noch gut aussieht, gehen wir einen Schritt weiter: Der nächste Ausdruck ist der String, der in eine Zeit umgewandelt werden soll:
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]"
_range := @Explode( @Texttotime( _convertString ) );
@Unique( @Month( _range ) );
REM "Obwohl wir den "unique" schon zurückliefern überschreiben wir hier den Rückgabewert einfach mit was anderem";
_convertString
Sieht das, was da rauskommt so aus: [01.09.2014 - 04.10.2014] (bzw. [09/01/2014 - 10/04/2014] auf englischem Client/Server) - ok, weiter
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]"
_timeRange := @Texttotime( _convertString )
_range := @Explode( _timeRange );
@Unique( @Month( _range ) );
REM "Obwohl wir den "unique" schon zurückliefern überschreiben wir hier den Rückgabewert einfach mit was anderem";
_timeRange
ok? - Weiter geht's:
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]"
_timeRange := @Texttotime( _convertString )
_range := @Explode( _timeRange );
@Unique( @Month( _range ) );
REM "Obwohl wir den "unique" schon zurückliefern überschreiben wir hier den Rückgabewert einfach mit was anderem";
_range
Immer noch ok?
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]"
_timeRange := @Texttotime( _convertString )
_range := @Explode( _timeRange );
_monthList := @Month( _range );
@Unique( _monthList );
REM "Obwohl wir den "unique" schon zurückliefern überschreiben wir hier den Rückgabewert einfach mit was anderem";
_monthList
Aha: hier kommt also eine Fehlermeldung, dass @Month ein Datum / eine Zeit erwartet... Komisch: Mit der letzten Ausgabe sah es doch aus, als ob wir eine Liste mit Datumswerten hätten...
Nun gut: Lesen wir mal die Designer- Hilfe zu @Explode:
Parameters
dateRange
Time-date range or time-date range list. The range of dates that you want to make into a text list. Specify a valid date-time range, not a string representation of one. For example, @Explode( "05/01/96 - 05/02/96" ) is invalid because the parameter is a string. Use @Explode( [05/01/96 - 05/02/96] ).
Aha, @Explode liefert also eine Textlist zurück... Dumm... Wir brauchen aber eine Liste mit Datumswerten... Wie bekommt man jetzt aus einer TextListe eine Datumsliste... Mit @TextToTime...
Also wird die Formel folgendermassen korrigiert:
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]";
_timeRange := @Texttotime( _convertString );
_range := @Explode( _timeRange );
_rangeDt := @TextToTime( _range );
_monthList := @Month( _rangeDt );
@Unique( _monthList );
Alles OK jetzt? - Nein, jetzt kommt ein anderer Fehler: "ERROR: Incorrect data type for operator or @Function: Text expected"
Dann wieder einen Schritt zurück:
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]";
_timeRange := @Texttotime( _convertString );
_range := @Explode( _timeRange );
_rangeDt := @TextToTime( _range );
_monthList := @Month( _rangeDt );
@Unique( _monthList );
REM "Obwohl wir den "unique" schon zurückliefern überschreiben wir hier den Rückgabewert einfach mit was anderem";
_monthList
Alles OK... Dann verursacht wohl der @Unique den Fehler (wenn _monthList ok ist). Also wieder die Designer- Hilfe prüfen:
Parameters
textlist
Text list. Any text list.
Also gut: @Unique braucht eine Text- Liste, @Month liefert aber eine Zahlenliste: Nächster Versuch:
Also weiter gehts im Text:
_start := @Text( co_Start );
_end := @Text( co_End );
_convertString := "[" + _start + " - " + _end + "]";
_timeRange := @Texttotime( _convertString );
_range := @Explode( _timeRange );
_rangeDt := @TextToTime( _range );
_monthList := @Month( _rangeDt );
@Unique(@Text( _monthList ) );
Voila: Der Code läuft...
Hoffe das hilft mal jemandem.