Search code examples
macrossassas-macro

Call execute in macro programme won't change the data file


I program this macro, who uses a call execute to put label of my old variable on my new variable. But, when I use the macro on different dataset, the call execute don't change the dataset.

%MACRO CHARTONUM2(file=,var=,nbvar=,newvar=,fmt=);
%DO aa=1 %TO &nbvar;
    DATA &file;
        set &file end=eof;
        &newvar&aa=input(put(&var&aa,$3.),3.);
        format &newvar&aa &fmt..;
        if eof then do;
            call execute('data &syslast; set &syslast;');
            call execute('label &newvar&aa = "' || strip(vlabel(&var&aa)) || '";');
            call execute('run;');
        end;
        drop &var&aa;
    RUN;
%END;
%MEND CHARTONUM2;

So, the dataset is dynamic with parameter "file". If I run this macro twice with 2 differents dataset, the call execute will search my variable in the 1st dataset. The rest is running good. Here is the log :

%CHARCHARTONUM(file=demohealth,var=SEX,deb=1,end=1,newvar=sexn,fmt=
sex);
MPRINT(CHARCHARTONUM):   DATA demohealth;
MPRINT(CHARCHARTONUM):   set demohealth end=eof;
MPRINT(CHARCHARTONUM):   sexn=input(put(SEX, $sex.),3.);
MPRINT(CHARCHARTONUM):   format sexn sex.;
MPRINT(CHARCHARTONUM):   if eof then do;
MPRINT(CHARCHARTONUM):   call execute('data &syslast; set &syslast;');
MPRINT(CHARCHARTONUM):   call execute('label &newvar = "' ||
strip(vlabel(SEX)) || '";');
MPRINT(CHARCHARTONUM):   call execute('run;');
MPRINT(CHARCHARTONUM):   end;
MPRINT(CHARCHARTONUM):   drop SEX_STD;
MPRINT(CHARCHARTONUM):   RUN;

WARNING: The variable SEX_STD in the DROP, KEEP, or RENAME list has never
         been referenced.
MPRINT(CHARCHARTONUM):   data WORK.ASIPRE ;
MPRINT(CHARCHARTONUM):   set WORK.ASIPRE ;
MPRINT(CHARCHARTONUM):   label sexn = "Sex";
MPRINT(CHARCHARTONUM):   run;

I want to launch this macro on any dataset... Is somebody have an idea ?


Solution

  • It has to do with when the value of &SYSLAST is updated and when the compilation of that data step happens.

    The compilation of the CALL EXECUTE data step happens before the inner data step is finished. The value of &SYSLAST has not been updated. Your version that works is because the value of &FILE is the same as &SYSLAST

    You can see it with this example:

    data test;
    x=1;
    label x="X Label";
    run;
    
    data temp;
    y=2;
    label y="Y Label";
    run;
    
    %macro NUMTOCHAR(file=,var=,newvar=,fmt=best.);
    data &file;
    set &file end=eof;
    &newvar=put(&var,&fmt);
    
    if eof then do;
        call execute('data &syslast; set &syslast;');
        call execute('label &newvar = "' || strip(vlabel(&var)) || '";');
        call execute('run;');
    end;
    run;
    
    %mend;
    
    %numtochar(file=test,var=x,newvar=xc);
    

    You see that the second data step is working on temp and not test.

    Change your code to:

    call execute('data &file; set &file;');