2
votes

I am having trouble with my conditional logic in my macro and assigning my libraries...

My issue: I have conditional macro logic (%IF/%THEN %DO) statements being executed before my libraries are assigned, and the logic is based on whether a dataset in the library exists.

I'm still learning how about macros in SAS and am not sure how to make sure my libraries are assigned first...

my program looks something like this:

%MACRO MyProg();
    SIGNON...
    RSUBMIT....
    LIBNAME TEMP "My.Qualifiers.To.Location" Disp=shr;


    %IF %SYSFUNC(EXIST(TEMP.FILE)) %THEN %DO;
    ....some datasteps....
    %END;

ENDRSUBMIT;
SIGNOFF;
%MEND;

%MyProg();

I can see from the log that %IF &SYSFUNC(EXIST(TEMP.FILE)) %THEN %DO; is false, and then the library is assigned afterwards.

How can I ensure that Libname statements are always executed first?

1
I'm not following. As written, the libname statement should always execute, before any code in the %DO block. Perhaps post your log. It's possible if you have options MLOGIC on that the log messages may be confusing. If you set options MPRINT NOSYMBOLGEN NOMLOGIC the order of the SAS statements should be clear.Quentin
@Quentin Macro syntax is always resolved/executed before any SAS code is... and I think that's really what the OP's issue is (combined with the complications inherent to RSUBMIT).Joe

1 Answers

2
votes

Your problem here is that the local macro processor is handling the macro syntax before it hands it off to the SAS/CONNECT server. So what happens when %MyProg() executes is first, all of the text inside it is treated as text and processed - returning this:

SIGNON...
    RSUBMIT....
    LIBNAME TEMP "My.Qualifiers.To.Location" Disp=shr;
    ....maybe some datasteps or not depending on what happened _locally_ with %if ....
    ENDRSUBMIT;
SIGNOFF;

That's correct behavior, and can often be quite useful. There are lots of situations where you might want to submit different RSUBMIT code blocks depending on something local. However, it's not what you want.

You will need to use macro quoting in order to prevent the macro from being resolved before you want it to. I'm not 100% sure about the timing here, but I think %nrbquote may be the correct quoting function to use.

However, further you have the problem that %IF needs to be inside a macro on the remote machine. Remember that what RSUBMIT does is submits code that another SAS.EXE (or unix/vax/etc. equivalent) is going to process. So if you want it to process %if [something] it has to be inside a macro. So what you really need is:

SIGNON;
RSUBMIT;
%MACRO MyProg();
    LIBNAME TEMP "My.Qualifiers.To.Location" Disp=shr;


    %IF %SYSFUNC(EXIST(TEMP.FILE)) %THEN %DO;
    ....some datasteps....
    %END;

%MEND;


%MyProg();
ENDRSUBMIT;
SIGNOFF;

As pointed out by Tom in comments to this answer, this isn't always safe - submitting a macro can be dangerous as it's not always parsed correctly - so tread lightly with this, and perhaps consider whether this can be handled in another way not using the macro language, or %includeing the macro from a file residing on the SAS/CONNECT server.