Falsche Fehler-Meldung bei K-Funktion Invalid third argument to function KSUBSTRB
Hallo,
beim Einlesen von Fremd-Daten muß ich mit substr() arbeiten. Da unser Base-Code seit ca. März 2009 unicodefähig ist verwende ich natürlich ksubstr().
Soweit so gut.
Leider arbeitet ksubstrB() nicht wie erwartet! Siehe Code:
length _nPOSNETTOWERT $44.;
_nPOSNETTOWERT="15,95"; output;
_nPOSNETTOWERT="39,5"; output;
_nPOSNETTOWERT="18,35"; output;
_nPOSNETTOWERT="4,97491638795986622073578595317725752508"; output;
_nPOSNETTOWERT="0"; output;
_nPOSNETTOWERT="19"; output;
_nPOSNETTOWERT="44,95"; output;
_nPOSNETTOWERT="12,5630252100840336134453781512605042017"; output;
run;
data bbb;
set aaa;
xxx=_nPOSNETTOWERT;
xxx2=_nPOSNETTOWERT;
if kindexc(xxx,',') then do;
xxx=ktrim(kscan(_nPOSNETTOWERT,1,','))||','||ksubstrB(kscan(_nPOSNETTOWERT,2,','),1,10);
end;
nPOSNETTOWERT=input(xxx, numx10.);
put xxx= _nPOSNETTOWERT= nPOSNETTOWERT=;
run;
Und der (gekürzte) LOG dazu:
1822 set aaa;
1823 xxx=_nPOSNETTOWERT;
1824 xxx2=_nPOSNETTOWERT;
1825 if kindexc(xxx,',') then do;
1826 xxx=ktrim(kscan(_nPOSNETTOWERT,1,','))||','||ksubstrB(kscan(_nPOSNETTOWERT,2,','),1,10);
1827 end;
1828 nPOSNETTOWERT=input(xxx, numx10.);
1829 put xxx= _nPOSNETTOWERT= nPOSNETTOWERT=;
1830 run;
NOTE: Invalid third argument to function KSUBSTRB.
xxx=15,95 _nPOSNETTOWERT=15,95 nPOSNETTOWERT=15.95
NOTE: Invalid third argument to function KSUBSTRB.
xxx=39,5 _nPOSNETTOWERT=39,5 nPOSNETTOWERT=39.5
NOTE: Invalid third argument to function KSUBSTRB.
xxx=18,35 _nPOSNETTOWERT=18,35 nPOSNETTOWERT=18.35
xxx=4,9749163879 _nPOSNETTOWERT=4,97491638795986622073578595317725752508 nPOSNETTOWERT=4.97491638
xxx=0 _nPOSNETTOWERT=0 nPOSNETTOWERT=0
xxx=19 _nPOSNETTOWERT=19 nPOSNETTOWERT=19
NOTE: Invalid third argument to function KSUBSTRB.
xxx=44,95 _nPOSNETTOWERT=44,95 nPOSNETTOWERT=44.95
xxx=12,5630252100 _nPOSNETTOWERT=12,5630252100840336134453781512605042017 nPOSNETTOWERT=12.5630252
NOTE: There were 8 observations read from the data set WORK.AAA.
NOTE: The data set WORK.BBB has 8 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.05 seconds
cpu time 0.01 seconds
Den Work-Around dazu habe ich auch schon, das ist also nicht das Problem, mich erschreckt die Qualität der Unicode-Unterstützung von SAS-92!
Der Work-Around (ohne LOG, ist nicht nötig, da fehlerfrei):
set aaa;
xxx=_nPOSNETTOWERT;
xxx2=_nPOSNETTOWERT;
if kindexc(xxx,',') then do;
xxx=ktrim(kscan(_nPOSNETTOWERT,1,','))||','||ksubstrB(scan(_nPOSNETTOWERT,2,','),1,10);
end;
nPOSNETTOWERT=input(xxx, numx10.);
put xxx= _nPOSNETTOWERT= nPOSNETTOWERT=;
run;
data bbb; /* Work-Around, Variante 2 (kscan() ausgelagert, fehlerfrei) */
set aaa;
xxx=_nPOSNETTOWERT;
xxx2=_nPOSNETTOWERT;
if kindexc(xxx,',') then do;
xxx2=kscan(_nPOSNETTOWERT,2,',');
xxx=ktrim(kscan(_nPOSNETTOWERT,1,','))||','||ksubstrB(xxx2,1,10);
end;
nPOSNETTOWERT=input(xxx, numx10.);
put xxx= _nPOSNETTOWERT= nPOSNETTOWERT=;
run;
Wie gesagt, der Work-Around ist gefunden, also kein Problem. Mich erschreckt die Qualität der Unicode-Unterstützung von SAS-92!
Wie sieht es bei anderen Anwendern mit Unicode aus? Haben andere Anwender bessere oder ähnliche Erfahrungen gemacht?
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)
- Anmelden oder Registrieren um Kommentare zu schreiben

Hilfe für meinen Kollegen
Hans, hier ein leerer Kommentar zu Deinem Beitrag.
Jetzt kannst/darst Du weiter berichten ;-)
Gruß, Andrea
Meldung doch berechtigt, aber ...
Hallo,
das Unicode-Thema bzw. die DBCS-Unterstützung durch SAS-92 ist ein undankbares Thema.
Ich glaubte
substrN()undksubstrB()würden zusammengehören, wie z.B.kupcase()der DBCS counterpart zuupcase()ist.Leider ist das nicht so, also ist die Fehler-/Note-Meldung berechtigt.
kscan()-Funktion gefunden und die Reparatur für SAS-93 zugesagt. Netter Nebeneffekt :-))Die Funktion
kscan()ist der DBCS counterpart zuscan().substrN()!Der Haupt-Unterschied zw.
substr()undsubstrN()ist für mich, dass man beisubstrN"über das Ende" vom "string" hinauslesen kann: If the length that you specify extends beyond the end of the string, the result is truncated at the end, so that the last character of the result is the last character of the string.Genau diese Funktionalität hatte ich gesucht, und geglaubt sie bei
ksubstrBgefunden zu haben. Dass das ein Denk-Fehler war ist mittlerweile klar.Dass der Workaround aus meinem Start-Beitrag geklappt hat war scheinbar Zufall. Hier der korrekte Workaround:
set aaa;
xxx=_nPOSNETTOWERT; /* Zahl mit zu vielen Nachkommastellen */
if kindexc(xxx,',') then do;
xxx=ktrim(kscan(_nPOSNETTOWERT,1,',')) /* Zahl mit max. 10 Nachkommastellen */
||','
||ksubstr(kscan(_nPOSNETTOWERT,2,',')
,1
,min(10,length(kscan(_nPOSNETTOWERT,2,',')))
);
end;
nPOSNETTOWERT=input(xxx, numx10.);
put xxx= _nPOSNETTOWERT= nPOSNETTOWERT= ;
run;
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)