Conditional expressions in Marco program

Reply
Occasional Contributor
Posts: 5

Conditional expressions in Marco program

[ Edited ]

Hi, i'm new the the fourm and to Sas. So please excuse the simplicity of my question.

 

Im trying to do the following:

 

data _null_;

    set dt1;

    call execute('%mp');

run;

 

%Macro mp;

    data _null_;

            retain delta 0;
            infile "&path.\SomeFile.csv" dsd firstobs=2
                 lrecl=32767 encoding="UTF-8" end=eof;
            input modstatus :$12.;

                   

           if not(upcase(substr(modstatus,1,3))='NEW') then 
                  delta=1;

 

           if eof then do;
                  if delta or _n_ le 9999 then
                        call symput('loadtype','DELTA');

                  if not(delta) and _n_ gt 9999 then
                        call symput('loadtype','FULL');
            end;

    run;

%mend;

 

This code will not evaluate the conditional expression with the Macro Processor, and therefor macro variable loadtype will not be set. So my question is, how can I get the conditional expression to evaluate as expected in this code setup?

 

Thank you for anwser's, and would really appriciate a explanation concering conditional expressions in this type of situation.

Cheers,

/Marcus

Esteemed Advisor
Esteemed Advisor
Posts: 7,217

Re: Conditional expressions in Marco program

[ Edited ]

Its nothing to do with the conditional.  It is to do with the process of execution.  A program is first sent to the macro pre-processor, this fully expands all the macro to plain base SAS code, this is then fed into the compiler.  Think of it this way, at the time the call symput is called, this is part of the macro pre-processor, it is not then going to feed back into the pre-processor, but only get fixed at that one point.  

 

To be honest though I don't see why you put any of that code in a macro anyways, what does dataset dt1 look like, and why would you need to execute the same code for each row in that dataset?  There is nothing in the data _null_ step which would require any sort of macro?  So, lets start from the beginning, what is it your trying to do?  Provide example test data.   I would also point out that you miss out the instance where _n_=9999.  Also, you can simplfy the code:

                  if delta or _n_ le 9999 then call symput('loadtype','DELTA');
                  else call symput('loadtype','FULL');

Finally your logic:

 if not(upcase(substr(modstatus,1,2))='NEW') then

Cannot be correct, the first 2 characters of modstatus cannot be the 3 characters of "NEW".

 

Perhaps this is the type of thing you were looking for, based off the condition, call either delta load or full load:

data have;
  retain delta 0;
  infile "somefile.csv" dsd firstobs=2 lrecl=32767 encoding="UTF-8" end=eof;
  input modstatus :$12.;
  if not(upcase(substr(modstatus,1,3))='NEW') then delta=1;
  if eof then do;
    if delta or _n_ le 9999 then call execute('%Load_Delta;');
    else call execute('%LoadFull;');
  end;
run;

Or if its the same macro with a paramter change:

    if delta or _n_ le 9999 then call execute('%LoadData (Type=Delta);');
    else call execute('%LoadData (Type=Full);'); 
Occasional Contributor
Posts: 5

Re: Conditional expressions in Marco program

Hi, thanks you for the reply! I forgot to mention that this code is just a very small rewrite from a bigger program to demonstrate my question. Should have used pseudo code instead. File content and data is EQ null relevance. =)

Yes, macro pre-processor is at the hearth of the problem. What I am interested in, is a way to use conditional logic that execute as expected with the above code scenario. Is there a technique I can use(external macro, conditional evaluation etc)?

So to sum up what I'm aiming for with this question, I'm looking for a very specific technical answer for this specific scenario.
Esteemed Advisor
Esteemed Advisor
Posts: 7,217

Re: Conditional expressions in Marco program

Simply put, no I am afraid.  I don't have access to the whole setup, so can't really avise on that, I gave a couple of workarounds, but its really something you need to assess in relation to the big picture.  I.e. how things fit together in the functiona design specification.  As I mentioned there is no reason why that code needs to be a macro, so why put it in a macro.  Your FDS should show a module flow diagram how each part of the program interacts with others, so you pull out the offending module and redesign that.  In 99.9% of instances macro language is not required.  There are other trechniques - putting parameters in datasets for instance rather than macro variables, which are far more robust and easy to validate and program against.

Occasional Contributor
Posts: 5

Re: Conditional expressions in Marco program

Hi, thanks for reply. Let me get the ball rolling with a ugly example that works, and hopefully some technical explenation to exactly how and why this is working, compared to the original code: 

 

filename kore catalog 'work.catalog.kore.source' lrecl=1024;

data _null_;
	set ds1;	
	file kore;
	put '%mp;';
run;

%inc kore;

/*as before*/

Macro program mp is unchanged.

Esteemed Advisor
Esteemed Advisor
Posts: 7,217

Re: Conditional expressions in Marco program

 

Try %nrstr():

http://www.datasavantconsulting.com/roland/call_exec.html

http://stackoverflow.com/questions/4152278/macro-variables-issue-when-using-call-execute

 

However I would still strongly advise that you re-assess your coding.  Functional Deisgn Specifications -> Coding in Base SAS (keep it simple smart!) -> Testing -> production lifecycle. 

Trusted Advisor
Posts: 1,114

Re: Conditional expressions in Marco program

If you correct the SUBSTR issue pointed out by @RW9 and replace the colon after "data _null_" (in macro MP) by a semicolon, I think, LOADTYPE should be set (as a global macro variable, because the local symbol table of macro MP is empty). But I share @RW9's opinion that a restructured code will probably make more sense. In particular, LOADTYPE would not be available inside the first data step (if that is where you tried to use it).

Occasional Contributor
Posts: 5

Re: Conditional expressions in Marco program

Hi, thanks for reply. Sorry, the colon and substr where typos in the rewrite. Loadtype is also global.

I try to use LOADTYPE inside the Macro program at a later stage.
Grand Advisor
Posts: 17,358

Re: Conditional expressions in Marco program

Use CALL SYMPUTX() instead of CALL SYMPUT()
The third optional parameter sets the macro variable to global.

call symputx('loadtype', full -g);
Occasional Contributor
Posts: 5

Re: Conditional expressions in Marco program

Hi, thanks for reply. Loadtype is Global.

SYMPUTX removes blanks, but is there another property that effects macro pre-processing?
Ask a Question
Discussion stats
  • 9 replies
  • 480 views
  • 2 likes
  • 4 in conversation