SAS: Как избежать бесконечного цикла в моем скрипте и позволить ему работать правильно? - PullRequest
0 голосов
/ 23 сентября 2018

мой скрипт сначала сканирует файл xls в нескольких подпапках, затем импортирует его и преобразует в целевые таблицы в соответствии с исходным файлом (от 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 голосов
/ 23 сентября 2018

У вас есть

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

И внутри этого цикла у вас есть:

%do i=1 %to &cnt;

Это может создать бесконечный цикл, потому что вы сбрасываете макропеременную i.Попробуйте изменить на:

%do j=1 %to &cnt;

В общем, для отладки таких ситуаций вы можете добавить операторы% put, чтобы увидеть, как меняется значение макропеременной.

...