DATA Step, Macro, Functions and more

Macro Expansion Confusion

Reply
N/A
Posts: 1

Macro Expansion Confusion

Can someone please tell me why the second "proc contents" below gives me errors, while the first one is OK?

The error is shown at the bottom. Thank you!


%macro foo(date);
work.abc_&date.
%mend;

%let date=201402;

data abc_&date.;
run;
data abc_&date._ext;
run;

%let input=%foo(&date.)_ext;
proc contents data=&input.;
run;

proc contents data=%foo(&date.)_ext;
run;


39         proc contents data=%foo(&date.)_ext;
MLOGIC(FOO):  Beginning execution.
SYMBOLGEN:  Macro variable DATE resolves to 201402
MLOGIC(FOO):  Parameter DATE has value 201402
SYMBOLGEN:  Macro variable DATE resolves to 201402
39         proc contents data=%foo(&date.)_ext;
                                          ____
                                          22
ERROR 22-322: Syntax error, expecting one of the following: ;, (, CENTILES, DATA, DETAILS, DIR, DIRECTORY, FMTLEN, LIB, MEMTYPE,
              MT, MTYPE, NODETAILS, NODS, NOPRINT, ORDER, OUT, OUT2, SHORT, VARNUM.

39         proc contents data=%foo(&date.)_ext;
                                          ____
                                          202
ERROR 202-322: The option or parameter is not recognized and will be ignored.

MPRINT(FOO):  work.abc_201402
MLOGIC(FOO):  Ending execution.
40         run;

Super User
Posts: 6,963

Re: Macro Expansion Confusion

Interesting. You might have to call TS for this, if nobody here has the answer.

If you get a good answer from TS, please post it here.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Valued Guide
Posts: 3,208

Re: Macro Expansion Confusion

this is working as expected:

43         %macro foo(date);

44           work.abc_&date.

45         %mend;

46        

47         proc contents data=%foo(m234019) ;

ERROR: File WORK.ABC_M234019.DATA does not exist.

48         run;

This also:

43         %macro foo(date);

44 work.abc_&date.

45         %mend;

46        

47         %let date=m234019 ;

48        

49         proc contents data=%foo(&date) ;

ERROR: File WORK.ABC_M234019.DATA does not exist.

50         run;

Trying several other ones and it is giving not any issue (9.4 sas UE).  Which version are you using?

I was suspicious on the lifetime of macrovars.

Declaring date by %let will be a global symbol table. Normal expectation is usage by a macro having a local temporay table.

SAS(R) 9.4 Macro Language: Reference, Third Edition .

By reading the schema SAS(R) 9.4 Macro Language: Reference, Third Edition there can be an exception.

As there is no explicit local symbol defined it is not created automically. Referencing a date macro var could go back to the global symbol table. There is global name used by with the same name there. This could causing some logic crack  

---->-- ja karman --<-----
Super User
Super User
Posts: 7,413

Re: Macro Expansion Confusion

(note SAS 9.3) I would guess that its to do with having to do a double pass on the instruction.  So in example 1 the pre-processor looks at:

proc contents data=&input.;

run;

And replaces the &input with: work.abc_201402.  You will see all other processing is resolved in the %let statement.

With the second example, it would require two passes to get resolution:

proc contents data=%foo(&date.)_ext;

run;

Pass1 =

proc contents data=work.abc_&date._ext;

run;

Pass 2 = Would resolve the &date.

However as there is only one pass

An alternative theory is that there are certain parts of code which cannot resolve macro code at run time.  For instance if you put the %foo on a set statement it doesn't resolve until after the set clause, so: set %foo(&date)_ext; also does not work, but putting data %foo(201402); set..; does work.

Would also be interested in a firm answer.  To note there are other ways of getting to what you want:

data _null_;

  date="201402";

  call execute('proc contents data=work.abc_'||strip(date)||'_ext; run;');

run;

Valued Guide
Posts: 3,208

Re: Macro Expansion Confusion

RW, can you replay the error? which system? as I am not able to see that one coming.

---->-- ja karman --<-----
Super User
Super User
Posts: 7,413

Re: Macro Expansion Confusion

Hi Jaap.

I am running on SAS 9.3 TS Level 1M2.  I get exactly the same issue as the OP and for my test I just put:

data want;

     set %foo(201402)_ext.;

run;

Simliar sort of errors.  It seems to be only in certain specific sections, i.e. data= for procedures, set for datasteps.

Valued Guide
Posts: 3,208

Re: Macro Expansion Confusion

This time I get a duplicated message, the reason looks to be space somewhere

I do not trust the symbol table.  Could you try with this?

Aside that space I have no errors ......    That space could be that the issue you are saying for procedures 


%macro foo(date);

%local date ;
  work.abc_&date.
%mend;

44        

45         %macro foo(date);

46           work.abc_&date.

47         %mend;

48        

49         data want ;

MLOGIC(FOO):  Beginning execution.

50         set %foo(201402)_ext ;

MLOGIC(FOO):  Parameter DATE has value 201402

SYMBOLGEN:  Macro variable DATE resolves to 201402

MPRINT(FOO):   work.abc_201402

MLOGIC(FOO):  Ending execution.

ERROR: File WORK.ABC_201402.DATA does not exist.

ERROR: File WORK._EXT.DATA does not exist.

---->-- ja karman --<-----
Super User
Super User
Posts: 7,413

Re: Macro Expansion Confusion

Yep, it doesn't even resolve that one, I just get the ERROR: File work._ext.data does not exist, as well.

Valued Guide
Posts: 3,208

Re: Macro Expansion Confusion

Ah I think to understand that.... SAS(R) 9.4 Macro Language: Reference, Third Edition

The macro is called in the middle of the tokenation process It puts text back and tokenation resumes. as this macro is in the middle of a word in does not get back/restart new tokenation.  Yes I see the same happening. The new word is not seen as a new word.     

---->-- ja karman --<-----
Super User
Posts: 9,687

Re: Macro Expansion Confusion

It is a magic, after I put %str() around it. It worked . Maybe these two words are location in different level which make SAS compile it as not what you think.

proc contents data=%str(%foo(&date.))_ext;

run;

Xia Keshan

Super User
Super User
Posts: 7,413

Re: Macro Expansion Confusion

Yes, with the %str() you are acutally hiding that part from the compilation check.  Do note the warning in the help though if you use that:

CAUTIONSmiley Very Happyo not use %STR to enclose other macro functions or macro invocations that have a list of parameter values.

Because %STR masks parentheses without a match, the macro processor does not recognize the arguments of a function or the parameter values of a macro invocation.

Valued Guide
Posts: 3,208

Re: Macro Expansion Confusion

this one also works:

47         data want;

48            set %upcase(%foo(date=201402)_ext) ;

ERROR: File WORK.ABC_201402_EXT.DATA does not exist.

49         run;

The behavior does me remember of some JCL Parameter string quirk. The ampersand should be seen outside a string before those in as string would be processed

The word parser here with sas has also something needed to reset the parse point. let those tech guys come.... 

---->-- ja karman --<-----
Ask a Question
Discussion stats
  • 11 replies
  • 380 views
  • 1 like
  • 5 in conversation