DATA Step, Macro, Functions and more

Need explantion why these lines of code does not work.

Accepted Solution Solved
Reply
Contributor
Posts: 29
Accepted Solution

Need explantion why these lines of code does not work.

I need help understanding why nwords will not resolve in the following lines of code:

%let drug=EXAMPLEONE, EXAMPLETWO;

%macro test;

Data test;

    drugs="&drug";

    dm = ',';

    mod = 'oq';

    nwords = countw(drugs, dm, mod);

    call symput('nwords',nwords);

    %do i=1 %to &nwords;

    drug&i=strip(scan(drugs, &i, dm, mod));

    %end;

run;

%mend test;

%test;

However this works:

%macro test;

Data _null_;

    drugs="&drug";

    dm = ',';

    mod = 'oq';

    nwords = countw(drugs, dm, mod);

    call symput('nwords',nwords);

run;

data test;

    drugs="&drug";

    dm = ',';

    mod = 'oq';

    nwords = countw(drugs, dm, mod);

    %do i=1 %to &nwords;

    drug&i=strip(scan(drugs, &i, dm, mod));

    %end;

run;

%mend test;

%test;

Thank you in advance!


Accepted Solutions
Solution
‎01-29-2015 09:56 AM
Super User
Super User
Posts: 7,407

Re: Need explantion why these lines of code does not work.

You are mixing up macro code and datastep code is the reason:

So, your macro test.  When it is called it will expand all the macro code into useable SAS code, then send that to the compiler.  So your call to symput doesn't get actioned until *after* all the macro has been evaluated, hence %do I=1 to &Nwords will result in a problem as nwords is not defined.  What are you attempting to do, as from the code above there is no reason to resort to macro code anyway.

Data test;

    drugs="&drug";  /* Don't know where this comes from? */

    dm = ',';

    mod = 'oq';

     array drug{100} $200.;  /* I am just assuming no more than 100 */

    do i=1 to countw(drugs, dm, mod);

      drug{I}=strip(scan(drugs,i,dm,mod));

    end;

run;

View solution in original post


All Replies
Solution
‎01-29-2015 09:56 AM
Super User
Super User
Posts: 7,407

Re: Need explantion why these lines of code does not work.

You are mixing up macro code and datastep code is the reason:

So, your macro test.  When it is called it will expand all the macro code into useable SAS code, then send that to the compiler.  So your call to symput doesn't get actioned until *after* all the macro has been evaluated, hence %do I=1 to &Nwords will result in a problem as nwords is not defined.  What are you attempting to do, as from the code above there is no reason to resort to macro code anyway.

Data test;

    drugs="&drug";  /* Don't know where this comes from? */

    dm = ',';

    mod = 'oq';

     array drug{100} $200.;  /* I am just assuming no more than 100 */

    do i=1 to countw(drugs, dm, mod);

      drug{I}=strip(scan(drugs,i,dm,mod));

    end;

run;

Contributor
Posts: 29

Re: Need explantion why these lines of code does not work.

Thank you so much for your explanation.  It was very informative and helpful.  If it is not too much, could you explain why the following does not work as well:

%macro test

Data test (drop=drugs dm mod nwords);

    drugs="&drug";

    dm = ',';

    mod = 'oq';

    nwords = countw(drugs, dm, mod);

    %do i=1 %to nwords;

    drug&i=strip(scan(drugs, &i, dm, mod));

    %end;

run;

%mend test;

;

%test

Is this because, similar as your explanation for my previous question, there is a mismatch with data step code and macro code?

Super User
Super User
Posts: 7,407

Re: Need explantion why these lines of code does not work.

Thats correct.  In step one your macro parts are expanded/resolved, as at that point nwords has not been created it fails.  So think of it this way, when the macro-preprocessor works it is trying to create a full base SAS program with nothing macro left in.  That code is then passed onto the compiler to be actioned.  So nwords is part of the datastep in the second step, but you are trying to reference it in macro language in step 1.

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 3 replies
  • 184 views
  • 2 likes
  • 2 in conversation