2013-08-08 6 views
1

Quelqu'un peut-il me dire pourquoi cela ne résout pas:SAS Macro boucle Do ne pas résoudre

/*put all transaction table names into a data set*/ 
/*(table names are of format transac_20130603_20130610 (date from and date to)*/ 
data transaction_tables; 
    set SASHELP.VTABLE (keep=libname memname); 
    where lowcase(substr(memname,1,8))='transac_' 

run; 
/*sort and add rownumbers*/ 
proc sql; 
create table transaction_tables as 
    select *, monotonic() as rownum 
     from transaction_tables 
      order by memname; 
run; 
/*find rownumber of first and last transaction tables with run dates before campaign start and after end date of campaign*/ 
data _NULL_; 
set transaction_tables; 
    if substr(memname,9,8)<=&pre_period_start. and substr(memname,18,8)>=&pre_period_start. then do; 
     call symput("r1", rownum); 
     stop; 
     end; 
run;   
data _NULL_; 
set transaction_tables; 
    if substr(memname,9,8)<=&max_enddate. and substr(memname,18,8)>=&max_enddate. then do; 
     call symput("r2", rownum); 
     stop; 
     end; 
run; 
%put &r1; %put &r2; 
/*r1 = 11, r2 = 27 - both resolving OK*/ 

/*get all relevant transaction table names where rownumbers are between r1 and r2*/ 
/*r1=11 and r2=27 so my transaction table name macros should run from t_0 to t_16/* 
%macro trans; 
%let y = %eval(&r2 - &r1); 
%do i=0 %to &y; 
data _NULL_; 
set transaction_tables; 
    if rownum = &r2 - (&r2 - &r1 - &i) then do; 
     call symput("t_&i", cats(libname, '.', memname)); 
     stop; 
     end; 
%end; 
%mend trans; 
%trans; 

%put &t_0; 
--WARNING: Macro variable "&t_0" was not resolved 

je ne suis pas tout à fait sûr pourquoi, mais de déconner avec quelques-unes des variables Je pense que le problème réside la dernière partie où il tente d'assigner des noms de tables à des macros i_&. Je pense que le problème est d'essayer de nommer une variable macro en essayant d'appeler une autre variable macro (en essayant de créer la macro t_0 en appelant & i quand i = 0). Je suppose que j'ai vissé quelque chose avec la syntaxe parce que je pense la logique est assez solide.

merci!

+0

Une bonne approche pour résoudre un problème de macro consiste à exécuter le code sans la macro. Tout ce que vous faites est la substitution de code ... faites le long chemin pour que le code s'exécute, commencez à mettre dans le code de la macro un peu à la fois. –

Répondre

1

Sans juger de l'utilité de ce que vous essayez de faire:

Il est une question de portée. Toute variable de macro que vous créez dans une macro n'existe que dans cette macro. Si vous voulez qu'il existe en dehors de votre macro, vous devez soit:

  • Créer la variable macro en code ouvert (pas dans une macro) et avant d'exécuter la macro.
  • Définir explicitement au global au sein de votre macro (avant la première mention), vous faites cela en écrivant:

    % t_0 mondiale;

modifier Notez également que pour mettre fin à un proc SQL, vous devez utiliser au lieu de quitter terme.

+0

hourra! merci :) –

+0

aussi, pouvez-vous penser à une façon plus utile de faire cela que j'ai? Je me rends compte que l'utilisation de rownumbers était un peu un hack et aurait préféré analyser chaque nom de table en essayant de trouver les bonnes plages de dates, au lieu de trier et d'utiliser rownumbers. Merci! –

1

approche alternative:

proc sql;                                
create table result as                             
    select cats(libname,'.',memname) as desired                          
    from dictionary.tables                             
    where substr(libname,1,8)='TRANSAC_'  
    and (scan(libname,2,'_')<=&pre_period_start. and scan(libname,3,'_')>=&pre_period_start.) 
    and (scan(libname,2,'_')<=&max_enddate. and scan(libname,3,'_')>=&max_enddate.) ; 

data _null_; 
    set result; 
    call symput(cats('R_',_n_),desired,'g'); 
run; 

Cela pourrait même être réécrite comme une étape en utilisant SQL 'dans' la clause. L'instruction SQL quit; est facultative, personnellement je ne l'utilise jamais.

+0

vient de remarquer ceci est très similaire à ce qui suit: http://stackoverflow.com/questions/18015218/automating-table-object-name-scan-and-search-in-sas –

+0

ha oui c'est très similaire, j'ai effectivement demandé cette question il y a une semaine, mais cette solution n'impliquait pas de macros de boucles, donc je n'ai pas eu le problème de% global que j'ai maintenant. Après avoir dit cela, votre façon de faire cela semble beaucoup plus simple que la mienne, donc je vais probablement arrêter d'essayer d'être intelligent avec une boucle do et juste utiliser ce que vous avez écrit ci-dessus. Je vous remercie!! –