Help using Base SAS procedures

Simple macro resolution fails in Procedures

Reply
Contributor
Posts: 23

Simple macro resolution fails in Procedures

The following code seems very simple yet produces an error.

-----------------------------------------------------------------
%let x=%str(a);
%put The value of macro x is -->&x<-- ;

* goes ok;
data test&x ; x=1 ; run ;

* goes wrong !!???!!??;
proc print out=test&x ; by x ; run ;
-----------------------------------------------------------------

The procedure produces this error (see below) and I can't work out why. Does anyone know?

-----------------------------------------------------------------
21 proc print out=test&x ; by x ; run ;
___
22
76

ERROR 22-322: Syntax error, expecting one of the following: ;, DATA, DOUBLE, HEADING, LABEL, N, NOOBS, OBS, ROUND, ROWS, SPLIT,
STYLE, UNIFORM, WIDTH.

ERROR 76-322: Syntax error, statement will be ignored.
-----------------------------------------------------------------

thanks
Phil Mason
Super User
Posts: 5,437

Re: Simple macro resolution fails in Procedures

Posted in reply to PhilMason
%str() works fine in procedure calls. I think you have to check your PROC PRINT syntax instead... I guess that your OUT= should be DATA=.

/Linus
Data never sleeps
Contributor
Posts: 23

Re: Simple macro resolution fails in Procedures

Sorry - I had tried a few different PROCs and the last one was a Proc Sort so I hadnt fixed the syntax. However, I still get the error with correct syntax....

21 proc print data=test&x ; run ;
_
200

ERROR 200-322: The symbol is not recognized and will be ignored.
N/A
Posts: 0

Re: Simple macro resolution fails in Procedures

Posted in reply to PhilMason
There is definitely something very strange going on!

When I ran this myself, the ‘data test’ step DIDN’T work OK – it created WORK.TEST and WORK.A instead of WORK.TESTA. This suggests that SAS is being passed more than just the ‘a’ when it tries to resolve &x.
Contributor
Posts: 23

Re: Simple macro resolution fails in Procedures

Posted in reply to deleted_user
You're right. It's like it has used a format and right justified the argument to %str, so it puts some spaces in front of it. That then explains what you find and the error. I look forward to hearing what the experts at SAS make of this.
Respected Advisor
Posts: 3,799

Re: Simple macro resolution fails in Procedures

Posted in reply to PhilMason
Disclaimer: I'm not an expert.

This problem is resolved with %UNQUOTE. Sometimes automatic unquoting does not work and UNQUOTEing is needed. Notice that the data step produces two data sets WORK.TEST and WORK.A. No error but not the intended result. Then in PROC PRINT data = TESTA causes another error. There are no spaces rather two tokens.
Super User
Posts: 5,437

Re: Simple macro resolution fails in Procedures

Posted in reply to deleted_user
Sorry, I was too quick there.
%str can cause some problems in other situations too, bot can often be resolved by using %unquote. Does this work for your situation? It seems to work with your example.

/Linus
Data never sleeps
N/A
Posts: 0

Re: Simple macro resolution fails in Procedures

Posted in reply to deleted_user
There is definitely something very funky happening:


188 %let x=b%str(a);
189 %put The value of macro x is -->&x<-- ;
The value of macro x is -->ba<--
190
191 * goes ok;
192 data test&x ; x=1 ; run ;

NOTE: Compression was disabled for data set WORK.TESTB because compression overhead would increase the size of the data set.
NOTE: Compression was disabled for data set WORK.A because compression overhead would increase the size of the data set.


And again


188 %let x = b%str(%a) ;
WARNING: Apparent invocation of macro A not resolved.
189 %put The value of macro x is -->&x<-- ;
WARNING: Apparent invocation of macro A not resolved.
The value of macro x is -->b%a<--
190
191 * goes ok;
192 data test&x ; x=1 ; run ;
NOTE: Line generated by the macro variable "X".
192 testb%a
_
_
_
22
22
22
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, (, /, ;, _DATA_, _LAST_, _NULL_.


So, again, I ask, why is %str(a) necessary?
I think you may be misusing %str(). Message was edited by: Chuck
N/A
Posts: 0

Re: Simple macro resolution fails in Procedures

Posted in reply to PhilMason
Personally, I'd just not use %str(a) in the first place.
%let x = a ;
should work just fine.

Here's some of my code using something like this.

%let N = %eval(&N + 1);
%let include_file = &BaseRP\&env\main\&home\&job..sas ;

%if "&on_this_system" = "BI" %then %do;

%global BI&N;
%local session_id;
%let session_id = BI&N;
%let all_sessions = %trim(&all_sessions) &session_id ;
%put all_sessions = &all_sessions ;

%if %length(&password) > 0 %then %do;
%RemoteBISignon(&session_id);

%local libdef;
%if %sysfunc(fileexist(&BaseRP\&env\IncludeLib\LibraryDefinitions.sas)) %then
%let libdef = &BaseRP\&env\IncludeLib\LibraryDefinitions.sas ;
%else
%let libdef = &BaseRP\Prod\IncludeLib\LibraryDefinitions.sas ;

%syslput environment = %bquote(&env) /remote=&session_id ;
%syslput include_file = &include_file /remote=&session_id ;
%syslput session_name = session&N /remote=&session_id ;
%syslput libdef = %bquote(&libdef) /remote=&session_id ;
rsubmit &session_id wait=no persist=no macvar=session&N SYSRPUTSYNC=yes
log="&base_file..log"
output="&base_file..out"
;
Contributor
Posts: 23

Re: Simple macro resolution fails in Procedures

Posted in reply to deleted_user
this was a simplified example to show the problem but did not explain why we need to use it. We do need to use quoting in this way. We did work out we could use %unquote to fix the problem, but we didnt understand why and so raised it here in hope of getting an explanation from someone in the know. Thanks to all that have responded so far though.
SAS Super FREQ
Posts: 8,868

Re: Simple macro resolution fails in Procedures

Posted in reply to PhilMason
Hi:
For the definitive answer, you might want to work with Tech Support. It was my understanding that any time you used a quoting function, SAS, behind the scenes used some kind of unprintable (hidden or hex) character to surround the text that was protected with the quoting function.

This SYMBOLGEN message implies the hidden characters:
[pre]
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been
unquoted for printing.

[/pre]

But from this Tech Support note, it looks like the above message gets issued by SYMBOLGEN, but the %STR hidden characters are not really removed:
http://support.sas.com/kb/22/353.html

I think the safest approach is to use %unquote as the note suggests. I have always found this paper on quoting functions to be good as a general explanation of how quoting functions worked:
http://www2.sas.com/proceedings/sugi24/Advtutor/p38-24.pdf

cynthia
Ask a Question
Discussion stats
  • 10 replies
  • 444 views
  • 0 likes
  • 5 in conversation