SAS-Makro-Definition zu VarListX

Mittlerweile gibt es zwar einen besseren Platz für Macro-Definitionen, aber voher stand die Macro-Definition hier im Blog, deshalb kopiere ich die Macro-Definition für VarListX erneut hier hin.

Hier folgt nun die Kurz-Form von VarListX:

%macro VarListX( dset  
               , sep=
%str( )  
               , pattern=
               );  
  
/*-----------------------------------------------------------------------------  
   *   Macro:      VarListX
   *   Programmer: Pete Lund     Hans Kneilmann
   *   Date:       Sept. 2000      Nov. 2006
   *   Purpose:    Create a macro variable that contains all the  
   *      variable names in a dataset, without those where pattern matches, separated by any
   *      character(s) specified. Can be used in KEEPs, DROPs, SQL  
   *      SELECTs, etc.  
   *  
   *   Parameters:  
   *      DSET - the name of the dataset (libref.member)  
   *      SEP  - character(s) to separate the variable names  
   *               (default is a space)  
   *      pattern - pattern in variable name, skip variable if match found
   *               (default is blanc, skip no variables)
   *  
   *-----------------------------------------------------------------------------*/  
  
%local ii dsid varlist;  
  
%global rc;  
  
%if &pattern. eq %then %let pattern=absoluter_blödsinn;
  
%let pattern=%upcase(&pattern.);
  
/* make sure that the dataset exists */  
  
%if %sysfunc(exist(&dset.)) EQ 0  
  
%then %do;  
    
%put %substr(###WARNING,4): &DSET. does not exist;  
    
%let rc=1;                  /* 1 if 'Fehler'  */  
    
%let varlist=;  
    
%goto Quit;  
  
%end;  
  
/*****  
        If it does exist, open the dataset. We'r going to create  
        a variable (varlist) which contains the list of variables  
        in the dataset, separated by the specified separator char-  
        acter(s). Start VarList off with the name of the first  
        variable in the dataset.  
  *****/  
  
%let varlist=;
  
%let dsid   =%sysfunc( open(&dset.) );  
  
%let feld=%upcase(%sysfunc( varname( &dsid., 1 ) ));  
  
%if %index(&feld., &pattern.) GT 0 %then %do;
    
%put INFO: Überspringe Feld &feld.;
  
%end;
  
%else %do;
    
%let varlist=&varlist.&feld.;  
  
%end;
  
  
/*****  
        Look through the rest of the variables in the dataset and  
        add them to the VarList value (with the sparator char in  
        between values).  
  *****/  
  
%do ii=2 %to %sysfunc(attrn(&dsid., nvars));  
    %
*et varlist=&varlist.&sep.%sysfunc( varname(&dsid., &ii.) );  

    
%let feld=%upcase(%sysfunc( varname( &dsid., &ii. ) ));  
    
%if %index(&feld., &pattern.) GT 0 %then %do;    /* 20070702: pattern statt _DM */
      
%put INFO: Überspringe Feld &feld. (pattern=&pattern.);
    
%end;
    
%else %do;
      
%if &varlist. NE %then %do;    /* 20070702: NE statt EQ, dann stimmt if-then-else */
        
%let varlist=&varlist.&sep.&feld.;  
      
%end;
      
%else %do;
        
%let varlist=&feld.;  /* falls für ii=1 galt: überspringe Feld */
      
%end;
    
%end;
  
%end;  
  
  
/*****  
        Close the dataset.  
  *****/  
  
%let rc =%sysfunc( close(&dsid.) );  
  
  %Quit:  
  
  
/*****  
        Write out the variable name list.  
  *****/  
  
&varlist.  
  
%mend VarListX;  

Irgendwie habe ich es geschafft den Original-Blog-Eintrag zu löschen. Eigentlich wollte ich nur den Fehler (siehe Beitrag Wolfgang Hornung, 29. Juni 2007, 13:20, siehe hier) korrigieren.

_DM

Hallo Herr Kneilmann,

so geht es natürlich auch, anstelle der Vertauschung der LET-Anweisung.

Aber eine Frage hätte ich noch zu dem Coding:

Was bedeutet dieses _DM in der zweiten Indexfunktion?
Ich konnte es nirgends in der Online-Doc finden.


%if %index(&feld., _DM) GT 0 %then %do;

Gruß
Wolfgang Hornung

Lösung des _DM-Rätsels

Hallo Herr Hornung,
das _DM ist einfach ein falscher Fehler. Glaube ich jedenfalls ...
Dieser VarListX ist (glaube ich) aus dem normalen VarList entstanden wegen einer Frage im Redscope-Forum. Da wollte jemand eine Liste aller Variablen, ausser den Wert-Variablen (glaube ich). Die Wert-Variablen endeten alle auf _DM.
Ich hatte den Macro dann zusammengebastelt und (scheinbar nur) leidlich getestet (siehe der vertauschte then-/else-Zweig).
Als ich ihn dann umgebaut habe, um ihn als allgemeine Lösung ins Forum zu stellen, hatte ich offenbar die von Ihnen genannte Stelle vergesessen zu ändern. Es muß heißen:

%if %index(&feld., &pattern.) GT 0 %then %do;
Die Macro-Funktion index will einfach einen String als 2. Parameter nach dem im String lt. Parameter 1 gesucht wird.
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)