SAS:如何避免脚本中的无限循环并使其正常运行?

时间:2018-09-23 16:16:17

标签: sas

我的脚本要做的是首先在多个子文件夹中扫描xls文件,然后将其导入并根据源文件(1至1)将其转换为目标表。它包括转置和创建新变量(用于目标表)。现在,我还没有准备将所有单独的表追加到1个大表中的脚本。

但是,我的脚本已经运行了5个小时,并且仍在运行。我相信这是无限循环的。有人注意到这里有什么问题吗?

 %macro drive(dir,ext);                                                
 %local filrf rc did memcnt name i;                                                                                                                                                                                
 %let rc=%sysfunc(filename(filrf,&dir));                               
 %let did=%sysfunc(dopen(&filrf));                                     

 %if &did eq 0 %then %do;                                              
   %put Directory &dir cannot be open or does not exist;                 
   %return;                                                              
 %end;                                                                 

 %do i = 1 %to %sysfunc(dnum(&did));                                   
   %let name=%qsysfunc(dread(&did,&i));                                                                                               

   %if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;          
      PROC IMPORT OUT=WORK.out&i  DATAFILE= "&dir/&name"        
        DBMS=csv REPLACE;
        delimiter='09'x;
        getnames=no;        
      RUN;

      proc contents data=out&i noprint out=data_info ;      
      run;

      data _null_;
       set data_info; 
       call symputx(compress("col"||VARNUM),compress(NAME));
       call symputx("cnt",_n_);
      run;

      data _null_;
        set WORK.out&i (obs=2);
        if _n_ = 2 then do;
          tcnt = 0;
            %do i=1 %to &cnt;
                if &&col&i not in ("","Total") then do;
                  trxm = &&col&i;
                  call symputx(compress("trxm"||tcnt),compress(trxm));
                  call symputx("tcnt",tcnt);
                  tcnt+1;
                end;
            %end;
        end;        
      run;

    %put &trxm0;        
    %put &trxm1;
    %put &trxm2;
    %put &tcnt;

data test&i (drop=  %do i=1 %to &cnt; &&col&i.. %end; ); 
        length station $10 voltage $10 year 8 month $20 transformer $10
        Day $20 Date Time MW_Imp MW_Exp MVAR_Imp MVAR_Exp MVA Power_Factor 8;
    format Time hhmm.;      
    set excelout end=last;      
    retain station voltage year month;      
    if _n_ = 1 then do;         
      station = VAR1;       
      voltage = VAR2;       
      year = input(VAR5,4.);        
      month = VAR3;         
    end;        
    if last then do;
      month = strip(put(intnx('month',input(catt(substr(month,1,3),'1960'),monyy.),1),monname10.));
          if month = "January" then year = year+1;      
    end;
        if _n_      4 then do;
        Day = VAR1;
      Date = VAR2;      
      Time = input(VAR3,time.);
      %do j=0 %to &tcnt;        
        transformer = "&&trxm&j..";
            MW_Imp = input(VAR%eval(4+%eval(&j*6)),best32.);
            MW_Exp = input(VAR%eval(5+%eval(&j*6)),best32.);
        MVAR_Imp = input(VAR%eval(6+%eval(&j*6)),best32.);
        MVAR_Exp = input(VAR%eval(7+%eval(&j*6)),best32.);
        MVA = input(VAR%eval(8+%eval(&j*6)),best32.);

        if MVA < 0.001 then Power_Factor = 0;       
        else Power_Factor = max(MW_Imp,MW_Exp)/MVA;
            output;         
      %end;         
    end;        
  run;

  %put &dir/&name;
  %end;                                                                                                                             

       %else %if %qscan(&name,2,.) = %then %do;                                                                                          
         %drive(&dir/%unquote(&name),&ext)                                                                                               
       %end;                                                                                                                             

 %end;                                                                 


 %let rc=%sysfunc(dclose(&did));                                       
%mend drive;                                                          

%let rc=%sysfunc(filename(filrf));                                    
%drive(/data/source/tttt/Files,xls)

这是因为代码是在另一个宏中编写的。我所做的是将代码从另一个宏复制到此脚本中。我可能是错的。请纠正我。

我相信我的逻辑可能使用不正确。

谁能发现哪里出了问题?

1 个答案:

答案 0 :(得分:1)

您有

%do i = 1 %to %sysfunc(dnum(&did));

在该循环中,您可以:

%do i=1 %to &cnt;

由于您正在重置宏变量i,因此可以创建无限循环。尝试更改为:

%do j=1 %to &cnt;

通常,要调试此类情况,可以添加%put语句以查看宏变量的值如何变化。