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

I am trying to use Macro to print dataset sashelp.cars and sashelp.cars.  But every time I try to run the code below it got errors.
How can I correct? Thank you.


%macro printz/parmbuff;
%let num=1;
%let dsname=%scan(&syspbuff,&num,',');
%do %while(&dsname ne);
proc print data=sashelp.&dsname;
run;
%let num=%eval(&num+1);
%let dsname=%scan(&syspbuff,&num);
%end;
%mend printz;

 

%printz(air,cars);

1 ACCEPTED SOLUTION

Accepted Solutions
tsap
Pyrite | Level 9

Just get rid of the third argument in your %SCAN details ( the ',').

%MACRO PRINTZ /PARMBUFF;
	%LET num=1;
	%LET DSNAME=%SCAN(&SYSPBUFF,&NUM);
	%DO %WHILE(&DSNAME NE);
		PROC PRINT DATA=SASHELP.&DSNAME;
		RUN;
		%LET NUM=%EVAL(&NUM+1);
		%LET DSNAME=%SCAN(&SYSPBUFF,&NUM);
	%END;
%MEND PRINTZ;

%PRINTZ(Air,Cars);

View solution in original post

6 REPLIES 6
tsap
Pyrite | Level 9

Just get rid of the third argument in your %SCAN details ( the ',').

%MACRO PRINTZ /PARMBUFF;
	%LET num=1;
	%LET DSNAME=%SCAN(&SYSPBUFF,&NUM);
	%DO %WHILE(&DSNAME NE);
		PROC PRINT DATA=SASHELP.&DSNAME;
		RUN;
		%LET NUM=%EVAL(&NUM+1);
		%LET DSNAME=%SCAN(&SYSPBUFF,&NUM);
	%END;
%MEND PRINTZ;

%PRINTZ(Air,Cars);
kedii_9
Fluorite | Level 6

Can I ask why ? Thank you.

tsap
Pyrite | Level 9

 

Using Default Delimiters in ASCII and EBCDIC Environments

If you use the SCAN function with only two arguments, then the default delimiters depend on whether your computer uses ASCII or EBCDIC characters. 
•If your computer uses ASCII characters, then the default delimiters are as follows: 
blank ! $ % & ( ) * + , - . / ; < ^ [Using Default Delimiters in ASCII and EBCDIC Environments]
In ASCII environments that do not contain the ^ character, the SCAN function uses the ~ character instead.

•If your computer uses EBCDIC characters, then the default delimiters are as follows: 
blank ! $ % & ( ) * + , - . / ; < ¬ | ¢ [Using Default Delimiters in ASCII and EBCDIC Environments]

If you use the modifier argument without specifying any characters as delimiters, then the only delimiters that will be used are delimiters that are defined by the modifier argument. In this case, the lists of default delimiters for ASCII and EBCDIC environments are not used. In other words, modifiers add to the list of delimiters that are explicitly specified by the charlist argument. Modifiers do not add to the list of default modifiers.

http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000214639.htm

 

By putting ',' as your third argument in your scan function details, you are telling it to only use those delimiter values and not the default values. So you get an error when you run your process. However, when you remove the third argument, the scan function uses the default list of delimiters as shown above. Included in this list is the open and close parentheses. So it doesn't see the parentheses as actual characters, but instead as only delimiters so when it looks for the first table name it pulls in the appropriate details.

 

Hope that helps.

Tom
Super User Tom
Super User

The parentheses are included in the value of the SYSPBUFF macro variable.

You can just remove them first and then start scanning the value.  Or if you know that users will never provide dataset options you could replace the single quotes in your list of delimiters with parentheses instead.  (Not sure why you wanted to include single quotes as one of the delimiters anyway.)

%let dsname=%scan(&syspbuff,&num,(,));

I would use a simple iterative %DO loop instead of adding all that extra code.

%macro printz/parmbuff;
%local num dsname;
%let num=%length(&syspbuff);
%if &num>2 %then %let syspbuff=%qsubstr(&syspbuff,2,&num-2);
%do num=1 %to %sysfunc(countw(&syspbuff,%str(,)));
  %let dsname=%scan(&syspbuff,&num,%str(,));
proc print data=sashelp.&dsname;
run;
%end;
%mend printz;
kedii_9
Fluorite | Level 6
Thank you for your response. It's really helpful !!
Tom
Super User Tom
Super User

Unless you actual macro is much more complicated than your example you do NOT need to use PARMBUFF option for this macro.  Just use something other than a comma in your list of dataset names.  The natural thing to use as a delimiter in SAS code is a space.

 

%macro printz(dslist);
%local i ds ;
%do i=1 %to %sysfunc(countw(&dslist,%str( )));
  %let ds=%scan(&dslist,&i,%str( ));
....
%end;
%mend printz;
%printz(class cars);

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 764 views
  • 0 likes
  • 3 in conversation