2013-08-08 2 views
1

Может кто-нибудь сказать мне, почему это не решает:SAS Macro Do Loop не разрешения

/*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 

я не совсем уверен, почему, но от возни с несколькими переменными я думаю, что проблема лежит с в последней части, где он пытается присвоить именам таблиц t_ & i макросам. Я думаю, проблема заключается в попытке назвать макро переменную при попытке вызвать другую макроперемену (пытаясь создать макрос t_0, вызывая & i, когда i = 0). я думаю, что я прикрутил что-то с синтаксисом, потому что я думаю, что логика довольно прочная.

спасибо!

+0

Хорошим подходом к решению проблемы макросов является выполнение кода без макроса. Все, что вы делаете, это замена кода ... сделайте это длинным способом, чтобы выполнить код, и начинайте вводить макрокод немного за раз. –

ответ

1

Без судить о полезности того, что вы пытаетесь сделать:

Это вопрос сфера. Любая макрокоманда, которую вы создаете в макросе, существует только внутри этого макроса. Если вы хотите, чтобы существовать вне макроса, вам необходимо либо:

  • Создания макропеременной в открытом коде (не в макросе) и перед выполнением макроса.
  • Установите его явно глобальный внутри макроса (до первого упоминания о нем), вы делаете это, написав:

    % мирового t_0;

редактировать Также отметим, что для завершения ргос SQL, вам нужно использовать бросить курить, а не бежать.

+0

ура! спасибо :) –

+0

также, можете ли вы придумать более полезный способ сделать это, чем я? я понимаю, что использование rownumbers было немного взломанным и предпочло бы сканировать каждое имя таблицы, пытаясь найти правильные диапазоны дат, вместо того, чтобы сортировать и использовать rownumbers. благодаря! –

1

Альтернативный подход:

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; 

Это даже может быть переписано как один шаг, используя SQL «в» статье. Заявление SQL quit; необязательно, лично я никогда не использую его.

+0

только что заметил, что это очень похоже на следующее: http://stackoverflow.com/questions/18015218/automating-table-object-name-scan-and-search-in-sas –

+0

ha да это очень похоже, я действительно спросил этот вопрос неделю назад, но это решение не включало никаких макросов make loop, поэтому у меня не было проблемы% global, с которой я сейчас сталкиваюсь. сказал, что ваш способ сделать это выглядит намного проще, чем у меня, поэтому я, вероятно, просто перестану пытаться быть умным с помощью цикла do и просто использовать то, что вы написали выше. Спасибо!! –