BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
BenGee
Fluorite | Level 6

Hello all,

 

I'm working with SAS9.4.

 

Can anyone explain why when using a string derived using CATS in a call to %nrquote, I get an error, but only when assigning the value to a macro variable via %LET?

 

Strangely, if I replace the %LET with a %PUT, the code succeeds.

 

Not sure if this is a bug or an expected behaviour.

 

If you run the code below from EG you'll see what I mean.

 

%let run_date= "31Jan2015:00:00:00"dt;

data _null_;
    date=datepart(&run_date);
	y=cats(year(date));
	y2=cats('20','15');
	y3=strip(year(date));

	call symput('YEAR', y);
	call symput('YEAR2', y2);
	call symput('YEAR3', y3);
run;

/*fails*/
%let SYSLAST = %nrquote(DATASET_&YEAR);
%let SYSLAST = %nrquote(DATASET_&YEAR2);

/*succeeds*/
%let SYSLAST = %nrquote(DATASET_&YEAR3);
%put SYSLAST = %nrquote(DATASET_&YEAR3);

The datastep is user-written precode to a DI job and the SYSLAST assignment is auto-generated. I was tasked with troubleshooting and resolving the issue. I got as far as understanding how to avoid the issue, but I can't explain the cause.

 

 

All help is welcomed.

 

Thanks,

Ben

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

In your data step the only difference in your three variables is the default length that SAS will use to create them.  Since you didn't tell SAS in advance what length to make the variables it will guess based on what it sees on the right hand side of the assignment statement.

 

The first thing you should change is to use CALL SYMPUTX() instead of the older CALL SYMPUT() this will automatically remove the trailing blanks from the value before creating the macro variable.

 

The real problem with your code is that you are attempting to use the macro quoting function in the value you are setting to a SAS system option.  SYSLAST is not just a macro variable, it is also the _LAST_ system option.   If you try to insert macro quotation marks into that value you will have created an invalid membername.

 

View solution in original post

4 REPLIES 4
Tom
Super User Tom
Super User

In your data step the only difference in your three variables is the default length that SAS will use to create them.  Since you didn't tell SAS in advance what length to make the variables it will guess based on what it sees on the right hand side of the assignment statement.

 

The first thing you should change is to use CALL SYMPUTX() instead of the older CALL SYMPUT() this will automatically remove the trailing blanks from the value before creating the macro variable.

 

The real problem with your code is that you are attempting to use the macro quoting function in the value you are setting to a SAS system option.  SYSLAST is not just a macro variable, it is also the _LAST_ system option.   If you try to insert macro quotation marks into that value you will have created an invalid membername.

 

BenGee
Fluorite | Level 6

Thanks for unravelling my problem Tom. Well explained and resolved!

 

If I'd replaced the _null_ with a physical dataset, I would have seen the variation in variable lengths from the dataset properties and potentially found the problem myself. I'll try this the next time I get a seemingly "invisble" problem.

 

This is how the code looks after incorporating your suggestions.

 

%let run_date= "31Jan2015:00:00:00"dt;

data _null_;
	length y $4;
	date=datepart(&run_date);
	y=year(date);
	call symputx('YEAR', y);
run;

%let SYSLAST = %nrquote(DATASET_&YEAR);

 

Tom
Super User Tom
Super User

But why are you using %NRQUOTE() macro function?  it is not doing anything in that situation. The result is the same as if you just did:

%let syslast=DATASET_&year ;

Try this to see that the %NRQUOTE() function is not having any impact.

 

data year1 year2;
  year=1; output year1;
  year=2; output year2;
run;
%let year=1;
%let syslast=%nrquote(YEAR&year);
%let year=2;
data _null_;
  set;
  put year=;
run;
data _null_;
 set &syslast;
 put year=1;
run;
BenGee
Fluorite | Level 6
I understand that %NRQUOTE isn't doing anything, but I have no choice. The
line of code using %NRQUOTE is automatically generated by DI studio, so I
have to live with it.

##- Please type your reply above this line. Simple formatting, no
attachments. -##

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 4 replies
  • 1046 views
  • 1 like
  • 2 in conversation