Hilfe! Datumskonvertierung

Hallo Redscope-Forum!

Ich bin gerade ein am Verzweifeln. Ich habe folgendes Problem mit einer SAS-Macrovariable.

Ich möchte in der Laufzeit einer Macrovariable einen Wert zuweisen, der aus einer anderen Macrovariable berechnet werden soll.

data _null_;
    
%let ausw_dat= '31dec2005'd; /* hier ändern: Analysedatum */    
    
%let ause_dat= %eval( intnx('Year',&ausw_dat,50,'END') );
    
    
%put &ausw_dat &ause_dat ;
run;

Das wirft mir leider Fehler.

Wenn ich es testhalber in der folgendermassen laufen lasse, dann funktioniert es.

data _null_;
    
/*Intnx testen*/
        
test = intnx('Year','31dec2005',50,'END');        
        
put test= ;
run;

Ich glaub ich mache einen ganz banalen Fehler und stehe ein bisschen auf dem Schlauch.
Vielleicht liegt es an der Sommerhitze oder der WM-Euphorie ???

Ich hoffe einer von Euch kann mir helfen!

Viele Grüße aus dem sonnigen Coburg

Andreas Windisch
HUK-COBURG-Bausparkasse AG

Gegenüberstellung

Hallo zusammen,

ich habe mal die verschiedenen Lösungsangebote gegenübergestellt, die teilweise funktionieren, teilweise nicht (teils klar, teils unklar).
Bestimmt weiss aber jemand warum das so ist.

%let ausw_dat= '31dec2005'd;
/* Lösung 1 */
%let ause_dat= %sysfunc(intnx(Year,&ausw_dat,50,END));
%put &ausw_dat %sysfunc(putn(&ause_dat,date.));
/* Lösung 2 */
%let ause_dat= %sysfunc(intnx('Year',&ausw_dat,50,'END'));
%put &ausw_dat %sysfunc(putn(&ause_dat,date.));
/* Lösung 3 */
data _null_;
call symput('ause_dat', put(intnx('Year',&ausw_dat,50,'END'),date.) );
run;
%put &ausw_dat &ause_dat ;
/* Lösung 4 */
%let ause_dat= %eval( intnx(Year,&ausw_dat,50,END));
%put &ausw_dat &ause_dat ;

Die Lösung 3 funktioniert, das ist klar, jedoch verstehe ich nicht, warum die Lösung 2 (gleiche Syntax von intnx, wie in Base) nicht, aber die Lösung 1 funktioniert.
Lösung 4 funktioniert nicht, da hier ja eigentlich auch nichts zu "evaluaten" ist, hier ist nach meinem Verständnis nur %sysfunc angebracht, s.a. Lösung 2.

Gruß
Wolfgang Hornung

Base-Faunction in Base oder mit sysfunc in Macro

Hallo,
wenn Base-Functions mit dem %sysfunc-Aufruf in der Macro Sprache aufgerufen werden, dann ist das fast das selbe wie ein Aufruf der gleichen Funktion direkt in SAS-Base. Betonung liegt auf fast.
Ein Unterschied ist z.B. das Einschließen der Steuer-Parameter YEAR und END in Gänsefüßchen (bei SAS-Base) oder nicht (in SAS-Macro).
Eine mögliche Erklärung ist, dass Macro-Sprache immer eine Quell-Sprache- (Quell-Code)-Umsetzung darstellt.
Es wird aus Quell-Code nach "gewissen" Regeln (Kontroll-Strukturen der Macro-Sprache im Macro-Code) neuer Quell-Code erzeugt.
Aus Text wird Text, oder aus einer Folge von Strings wird eine Folge von Strings. Deshalb will die Macro-Sprache (selten) Gänsefüßchen. Beispiel:

%let Name=Hans;    /* Variable "Name"  enthält den String "Hans" */
%let Alter=49;     /* Variable "Alter" enthält den String "49"   */

Nur in Ausnahme-Fällen konvertiert SAS-Macro Strings in Ziffern. Zum Beispiel in einer %if-Anweisung.
Deshalb geht die Abfrage %if &name. eq VA-Mainz %then %put Treffer; immer schief, denn der Bindstrich ist für SAS-Macro ein Minus und mit den Buchstaben "VA" und "Mainz" läßt sich nicht rechnen ...
Ansonsten siehe unten. Im Beitrag von Armageddon, 4 Juli, 2006 - 14:29 stehen ein paar Worte zu den Besonderheiten von sysfunc
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)

Hallo!Eine rein

Hallo!

Eine rein makrobasiserte Lösung geht auch. Die sieht dann so aus.

%let ausw_dat= '31dec2005'd; /* hier ändern: Analysedatum */
%let ause_dat= %sysfunc( intnx(Year,&ausw_dat,50,END) );
%put &ausw_dat %sysfunc (putn (&ause_dat,date.));

Innerhalb der %sysfunc-Makrofunktion muss man die SAS Funktionen putn bzw. putc verwenden.

Gruß
Klaus

Formattierte Ausgabe von SYSFUNC

Hallo,

man kann bei %Sysfunc das Format zur Ausgabe des Ergebnisses in einem zweiten Parameter mitgeben. Die Lösung sieht dann so aus:

%let ausw_dat= '31dec2005'd; /* hier ändern: Analysedatum */
%* Hier gleich wieder in die Textdarstellung eines SAS-Datumswerts umgewandelt;
%let ause_dat= "%sysfunc( intnx(Year,&ausw_dat,50,END),date9. )"d;
%put &ausw_dat &ause_dat;

Gruß

Wilfried Schollenberger

Formattierte Ausgabe von SYSFUN

Entschuldigung: Ein bedienfehler führte zu einem doppelten eintrag

Äpfel und Birnen

Hallo,
ich glaub hier werden Äpfel und Birnen mit einander verglichen.
Das %eval kann die Funktion intnx nicht ausführen, weil es keine Macrofunktion ist. Außerdem, selbst wenn das %eval es könnte, muß man bedenken, das es keine in Häkchen gefaßte Strings im Macro gibt (siehe hierzu auch %sysfunc für das ausführen von SCL-Funktion zum Zeitpunkt der Macrobearbeitung).

Wenn es den unbedingt Macrovariablen sein müssen, könnte man es so lösen:

%let ausw_dat='31dec2005'd;

data _null_;
   
call symput('ause_dat', put(intnx('Year',&ausw_dat,50,'END'),best32.) );
run;

data _null_;
   
%put &ausw_dat &ause_dat ;
run;

Man könnte auch alles ein einem Datastep zusammen fassen, je nach SAS Version kann es dann aber Probleme mit dem Inhalt der Macrovariablen geben, da die Inhalte teilweise erst nach verlassen des Datastep aktualisert werden.

Gruß Guido

Äpfel & Birnen, Teil 2

Auch ich sehe hier ein großes Äpfel & Birnen Problem!
Auch in der obigen Lösung bzw. Antwort von Armageddon, 4 Juli, 2006 - 14:29 ist noch ein Äpfel&Birnen-Vermischungs-Problem:

data _null_;
%put &ausw_dat &ause_dat ;
run;

macht in dieser Form absolut keinen Sinn, hier wird SAS-Base und SAS-Macro "gefährlich" vermischt. Es passiert in diesem Beispiel nix falsches, aber es ist in dieser Form einfach nicht korrekt.
Korrekt wäre:

data _null_;
  put "&ausw_dat &ause_dat";  /* ggf. den Befehl file log; davor */
run;

oder korrekt wäre:

%put &ausw_dat &ause_dat ;

Ganz einfach ohne data _null_ drum rum.

Im ersten Beitrag (awindisch, 4 Juli, 2006 - 13:40) ist das Äpfel&Birnen-Vermischungs-Problem riesig groß und führt genau zu dem Effekt: Es klappt nicht.
Warum? Weil der SAS-Macro-Code vor dem SAS-Base Data Step bearbeitet wird. Es findet ein ständiger Wechsel zw. SAS-Macro-Code-Bearbeitung und SAS-Base-Code-Bearbeitung (also Data- bzw. Proc-Steps) statt!

  • Wenn man zur Data-Step-Bearbeitungs-Zeit eine Macro-Variable beschreiben will, dann geht das nur mit call symput.
  • Wenn man zur Data-Step-Bearbeitungs-Zeit eine Macro-Variable lesen will, dann geht das nur mit call symget.

Also sollte der Code im ersten Beitrag (awindisch, 4 Juli, 2006 - 13:40) entweder so

%let ausw_dat= '31dec2005'd; /* hier ändern: Analysedatum */
%let ause_dat= %eval( intnx('Year',&ausw_dat,50,'END') );

%put &ausw_dat &ause_dat ;

oder so

data _null_;
  ausw_dat= '31dec2005'd; /* hier ändern: Analysedatum */
  ause_dat= intnx('Year',&ausw_dat,50,'END') ;

  put ausw_dat date. " " ause_dat date.;
  call symput("ause_dat", put(ause_dat, date.)); /* falls man ...   */
  call symput("ausw_dat", put(ausw_dat, date.));   /* ... unbed. will */
run;
%put &ausw_dat &ause_dat ;

aussehen. Alles andere ist (an dieser Stelle) nicht sinnvoll, jedesmal meiner Meinung nach ...
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)

Äpfel & Birnen, Teil 3

Vollkommen richtig, an der Stelle hab ich schlammpig gearbeitet und nur faul kopier.

Gruß
Guido