BookmarkSubscribeRSS Feed
PatRoss
Calcite | Level 5

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;

11 REPLIES 11
jakarman
Barite | Level 11

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 --<-----
RW9
Diamond | Level 26 RW9
Diamond | Level 26

(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;

jakarman
Barite | Level 11

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

---->-- ja karman --<-----
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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.

jakarman
Barite | Level 11

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 --<-----
RW9
Diamond | Level 26 RW9
Diamond | Level 26

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

jakarman
Barite | Level 11

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 --<-----
Ksharp
Super User

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

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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:

CAUTION:Do 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.

jakarman
Barite | Level 11

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 --<-----

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 1819 views
  • 1 like
  • 5 in conversation