1

これが解決しない理由を誰かに教えてもらえますか:

/*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 マクロに割り当てようとしている最後の部分に問題があると思います。問題は、別のマクロ変数を呼び出そうとしているときにマクロ変数に名前を付けようとしていることにあると思います (i=0 のときに &i を呼び出してマクロ t_0 を作成しようとしています)。ロジックがかなり健全だと思うので、構文で何かを台無しにしたと思います。

ありがとう!

4

2 に答える 2

1

あなたがやろうとしていることの有用性を判断せずに:

範囲の問題です。マクロ内で作成したマクロ変数は、そのマクロ内にのみ存在します。マクロの外部に存在させたい場合は、次のいずれかを行う必要があります。

  • マクロを実行する前に、(マクロではなく) オープン コードでマクロ変数を作成します。
  • マクロ内で (最初に言及する前に) グローバルに明示的に設定するには、次のように記述します。

    %グローバル t_0;

edit また、proc sql を終了するには、run の代わりに quit を使用する必要があることに注意してください。

于 2013-08-08T10:58:25.223 に答える
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 'into' 句を使用して 1 つのステップとして書き直すこともできます。SQLquit;ステートメントはオプションです。個人的には使用しません。

于 2013-08-08T13:02:25.743 に答える