Variable Dateierstellung in Abhängikeit von Tabelleninhalt

Hallo,

ich habe folg. Frage.

Annahme:
- Tabelle mit 50.000 Zeilen
- Eine Spalte enthält unsere Bundesländer

Die Datei soll so aufgesplittet werden, dass ich später für jedes Bundesland eine neue Tabelle habe.

Ich weiß dass man mit einer einfachen If-Then Abfrage die Daten aufteilen kann.

Ich hätte lieber folgendes, da ich dies auch für andere Situationen anwenden möchte:

- Daten nach Bundesland sortieren
- Im Rahmen z.B. einer Schleife soll er erkenn, wenn ein neues Bundesland auftaucht und soll dann eine neue Datei erstellen. (Hierum gehts mir !!!!).

Schon vorab vielen Dank für Eure Hilfe.

Frank

Einfache Makrolösung

Hallo Frank,

relativ simpel ist die Lösung mit PROC SQL und einer Makroschleife. Eine Sortierung ist hierzu nicht nötig. Ich habe der Einfachheit angenommen, dass die resultierenden Datensätze nach den Bundesländern heißen sollen. Bei Sonderzeichen im Ländernamen (z.B. Bindestrich in Nordhrhein-Westfalen) müsste man die Dateinamen natürlich modifizieren.

Schöne Grüße
Alex

data Have ;
length Bundesland $ 20 ;
input Bundesland $ TestVariable ;
infile cards ;
cards;
Hamburg 1
Hamburg 2
Hamburg 3
Hessen 4
Hessen 5
Hessen 6
Bayern 7
;
run;

proc sql noprint;
select distinct Bundesland
into :LaenderListe separated by ' '
from Have
order by Bundesland
;
%let N_Laender = &sqlobs ;
quit;

%macro LaenderAufteilen;

%local ElseOrBlank Land ;

data &LaenderListe ;
set Have ;
%let ElseOrBlank =; /* Leer für das erste Budnesland; ab dem zweiten "else". Dies ist performanter als aufeinanderfolgende, unverknüpfte if-Bedingungen, die für allesamt für jede Observation geprüft werden müssten.*/
%do i = 1 %to &N_Laender ;
%let Land = %scan( &LaenderListe, &i ) ;
&ElseOrBlank if BundesLand = "&Land" then output &Land ;
%let ElseOrBlank = else ;
%end;
run;
%mend LaenderAufteilen;

%LaenderAufteilen;

Vielen Dank

Hallo Alex,

super es funktioniert alles. Vielen Dank.

Besonders gut hat mir im übrigen das Beispiel mit "ElseorBlank" gefallen. Das kannte ich bisher nicht.

Das Thema Makrovariablen ist für mich relativ neu. Kannst Du mir noch sagen, wie weit die Variablen gültig sind?
Also z.B. die mit "%local" gekennzeichneten sind vermutlich nur in dem Makro gültig, in dem sie definiert wurden.

Wie weit ist z.B. N_Laender gültig?

Meine letzte Frage: Wofür ist eigentlich das Prozentzeichen vor den einzelnen Befehlen im Makro. Was sagen die aus?
Es gibt doch auch Makros ohne dieses Zeichen.

Also nochmal Vielen Dank und schöne Grüße

Frank

Hallo Frank, N_Laender ist in

Hallo Frank,

N_Laender ist in diesem Fall global gültig, da die Macrovariable außerhalb des Macros definiert wurde.

Generell gilt:
Alle Variablen, die außerhalb des Macros definiert wurden, sind global gültig.

Alle Variablen, die innerhalb des Macros mit Werten gefüllt werden, und Parameter sind lokal und in den Macros gültig, die aus einem Macro heraus aufgerufen werden.

Es sei denn, es existiert bereits eine globale Variable desselben Namens und man hat nicht vorher eine lokale Variable definiert. Deshalb sollten lokale Variablen auch als solche definiert werden, damit sie nicht die Werte globaler Variablen, soweit die schon existieren, überschreiben.

%symdel Var;
%macro test;
%Let Var = lokal;
%Put lokale Var =&Var;
%mend;
%test;
/* Fehler, da global unbekannt */
%Put globale Var =&Var;

/* Überschreiben des globalen Wertes */
%Let Var=global;
%Put globale Var =&Var;
%macro test;
%Let Var = lokal;
%Put lokale Var =&Var;
%mend;
%test;
%Put globale Var =&Var;

/* zwei getrennte Variablen */
%Let Var=globlal;
%Put globale Var =&Var;
%macro test;
%local Var;
%Let Var = lokal;
%Put lokale Var =&Var;
%mend;
%test;
%Put globale Var =&Var;

Das Prozentzeichen steht vor Befehlen, die die Ausführung des Macros steuern. Diese Befehle werden nicht mit in die Ausgabe übernommen.
Bsp:

%macro test (Var);
%PUT %Length(&Var);
%mend;
%test( testen );

berechnet die Länge einer &Macrovariable zur Erstellungszeit des Macros und gibt diese in das Log aus.

%macro test (Var);
Data _NULL_;
a = Length("&Var.");
put a;
run;
%mend;
%test( testen );

Hier wird die Länge der Variablen erst zur Laufzeit ermittelt und ins Log ausgegeben.

Schöne Grüße

Jan