2013-08-08 5 views
1

를 해결하지 않으면 아무도 말해 줄 수 :SAS 매크로 마 루프

/*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_ & 매크로에 할당하려고하는 마지막 부분. 나는 문제가 다른 매크로 변수를 호출하려고 시도하는 동안 매크로 변수의 이름을 지정하는 것으로 생각한다. (매크로가 0 = 0 일 때 &을 호출하여 매크로 t_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

하, 예, 매우 비슷합니다, 나는 실제로 물었다. 그 질문은 일주일 전이지만, 그 해결책은 어떤 do 루프 매크로도 포함하지 않았으므로 지금 나는 글로벌 문제가 없었습니다. 이런 식으로하는 당신의 방법은 내 것보다 훨씬 간단 해 보입니다. 그래서 do 루프로 똑똑해지기를 멈추고 위에서 작성한 것을 사용하는 것을 멈추게 될 것입니다. 고맙습니다!! –