WS

Datenabhängiges Ausführen von Macros

Einführung

Die Funktion call execute() ermöglicht u.a., die Ausführung von Programmen (Macros) über Daten zu steuern. Ein einfaches Beispiel ist das Vergleichen gleichnamiger Dateien in zwei SAS-Libraries:

     %macro compare(data1,data2);
       title "Vergleiche &data1 und &data2";
       Proc compare data=&data1 compare=&data2;
       RUN;
     %mend;
     Proc sql;
      create table work.liste
        as select memname
        from dictionary.tables
        where libname="LIB1" and memtype="DATA";
     QUIT;
     Data _null_;
      Set work.liste;
      macroCall = '%compare (LIB1.'!!memname!!", LIB2"!!memname!!");";
      call execute(macroCall);
     RUN;

Mit diesem Programm wird jede Datei aus LIB1 mit der (hoffentlich vorhandenen) Datei in LIB2 verglichen.

Problem

Der Macroaufruf wird bei der Ausführung von call execute() ausgeführt. Eventuell erzeugte Proc- und Datasteps werden aber erst nach dem Ende des Datasteps und dann auch nur nacheinander ausgeführt.

Wenn nun das Macro etwas komplexer ist, und die korrekte Ausführung davon abhängt, dass Macro-Anweisungen und Proc/Datasteps in der richtigen Reihenfolge ausgeführt werden, führt die Ausführung des Macros in call execute() zu einem fehlerhaften Verhalten. Ein Beispiel wäre die Prüfung des Ergebnisses mit der automatischen Macrovariablen &syserr.

Um dieses Problem zu vermeiden, muss die Ausführung des Macros verzügert werden. Das wird mit der Macro-Funktion %nrstr() erreicht. Der Macro-Aufruf wird dann von call execute() wie Text behandelt und erst nach dem Ende des Datasteps vom Program-Manager ausgeführt.

Das folgende Beispiel zeigt den Unterschied.

     %macro ttt;
      %Let i = %eval(&i+1);
      %put ttt starts &i;
      Data _null_;
       PUT "Datastep &i";
      RUN;
      %put ttt ends &i Fehlercode &syserr;
     %mend;

* This example will show the problem:
  Any Macro-Code after the Datsstep will execute
  before the datstep has executed;

     %let i=0;
     Data _null_;
      do j = 1 to 3;
       call execute('%ttt');
      end;
     RUN;

* This will produce the right results;

     %let i=0;
     Data _null_;
      do j = 1 to 3;
       call execute('%nrstr(%ttt)');
      end;
     RUN;

Im ersten Fall werden zuerst die Macro-Ausgaben und dann der Datastep ausgeführt. Nur nach dem zweiten Datastep mit %nrstr werden Macrocode und Datasteps in der erwarteten Reihenfolge ausgeführt.

zurück zum Anfang

© WS Unternehmensberatung und Controlling-Systeme GmbH
Friedrich-Weinbrenner-Straße 20
69126 Heidelberg

Tel.: 06221 / 401 409
Fax: 06221 / 401 422

EMail: info @ ws-unternehmensberatung.de

Amtsgericht Mannheim, HRB 335485
Geschäftsführer: Wilfried Schollenberger