BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Babloo
Rhodochrosite | Level 12

@Reeza @PaigeMiller  In the qlist macro, I don't want to create other macro varible, my_list. Can we tackle this without creating new macro varaible? Only varlist (per my post, it is 'Parameter') macro variable to be used in the code below.

 

filename qlist url 'https://raw.githubusercontent.com/sasutils/macros/master/qlist.sas';
%include  qlist;

%let varlist = Data Management,Operations,Sales; 

%let my_list= %qlist(%quote(&varlist.), paren=0, comma=1, delimit=',', dsd = 0, quote=2);

%put &my_list.;
PaigeMiller
Diamond | Level 26

@Babloo wrote:

@Reeza @PaigeMiller  In the qlist macro, I don't want to create other macro varible, my_list. Can we tackle this without creating new macro varaible? Only varlist (per my post, it is 'Parameter') macro variable to be used in the code below.

 

filename qlist url 'https://raw.githubusercontent.com/sasutils/macros/master/qlist.sas';
%include  qlist;

%let varlist = Data Management,Operations,Sales; 

%let my_list= %qlist(%quote(&varlist.), paren=0, comma=1, delimit=',', dsd = 0, quote=2);

%put &my_list.;

Yes, you don't need to use my_list, you can use varlist on the left of the equal sign

--
Paige Miller
Babloo
Rhodochrosite | Level 12

@PaigeMiller Like this,

 

filename qlist url 'https://raw.githubusercontent.com/sasutils/macros/master/qlist.sas';
%include  qlist;

%let varlist = Data Management,Operations,Sales; 

%let  varlist = %qlist(%quote(&varlist.), paren=0, comma=1, delimit=',', dsd = 0, quote=2);

%put &varlist.;
Quentin
Super User

@Babloo wrote:

@PaigeMiller Like this,

 

filename qlist url 'https://raw.githubusercontent.com/sasutils/macros/master/qlist.sas';
%include  qlist;

%let varlist = Data Management,Operations,Sales; 

%let  varlist = %qlist(%quote(&varlist.), paren=0, comma=1, delimit=',', dsd = 0, quote=2);

%put &varlist.;

Since you're dealing with values passed in from elsewhere, you might want to change to using %superq() instead of %quote() to mask any macro triggers, and also change to passing quote=1 to get single quotes around each item of the list.  Also note that you don't have to assign the new quoted list to a macro variable at all.  You can just call %qlist where you want to generate the quoted list, e.g.:

 

options mprint ;

data _null_ ;
  call symputx('varlist','Data Management,Operations,Sales,Franks&Beans') ;
run ;

%put varlist=%superq(varlist) ;

proc print data=have noobs;
  where Division in ( %qlist(%superq(varlist), paren=0, comma=1, delimit=',', dsd = 0, quote=1) ) ;  
run;
BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Babloo
Rhodochrosite | Level 12

@PaigeMiller just calling %qlist macro is throwing an error.

 

90 ! %qlist(%superq(varlist), paren=0, comma=1, delimit=',', dsd = 0, quote=1) ) ;
     -
     22
WARNING: Apparent invocation of macro QLIST not resolved.
90                         %qlist(%superq(varlist), paren=0, comma=1, delimit=',', dsd = 0, quote=1) ) ;
                           -
                           76
ERROR: Syntax error while parsing WHERE clause.
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant, 
              a missing value, -.  
ERROR 76-322: Syntax error, statement will be ignored.
Quentin
Super User

@Babloo wrote:

@PaigeMiller just calling %qlist macro is throwing an error.

 

90 ! %qlist(%superq(varlist), paren=0, comma=1, delimit=',', dsd = 0, quote=1) ) ;
     -
     22
WARNING: Apparent invocation of macro QLIST not resolved.
90                         %qlist(%superq(varlist), paren=0, comma=1, delimit=',', dsd = 0, quote=1) ) ;
                           -
                           76
ERROR: Syntax error while parsing WHERE clause.
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant, 
              a missing value, -.  
ERROR 76-322: Syntax error, statement will be ignored.

You still need to run the %include to compile the macro, before calling it:

 

filename qlist url 'https://raw.githubusercontent.com/sasutils/macros/master/qlist.sas';
%include  qlist;

If you don't want to run that code in every session when you use the macro, then you would need to download qlist.sas, and put qlist.sas in your autocall library search path.  Then when you call %qlist() the first time in a SAS session, SAS will search the autocall directories for qlist.sas and it will compile the macro.

BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
AhmedAl_Attar
Rhodochrosite | Level 12

@Babloo 

 

I typically do the following to quote separated values within a macro variable

%let parameter=Data Management,Operations,Sales;
%put &=parameter;
%let parameter=%str(%')%qsysfunc(tranwrd(&parameter,%str(,), %str(%',%')))%str(%');
%put &=parameter;

/* To use this macro variable in a where clause, I would use %unquote() */
Where Division in (%unquote(&parameter));

Hope this helps

Babloo
Rhodochrosite | Level 12

@AhmedAl_Attar  I'm getting an error

 

33   %put &=parameter;
PARAMETER=Sales,Operations
34   %let parameter_2=%str(%')%qsysfunc(tranwrd(&parameter,%str(,), %str(%',%')))%str(%');
SYMBOLGEN:  Macro variable PARAMETER resolves to Sales,Operations
ERROR: The function TRANWRD referenced by the %SYSFUNC or %QSYSFUNC macro function has too many arguments.
35   %put &=parameter;
SYMBOLGEN:  Macro variable PARAMETER resolves to ''
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
PARAMETER=''
36   
PaigeMiller
Diamond | Level 26

Hello @Babloo 

 

Another reason why I recommend using the %qlist macro is that someone has already done the very hard work of creating macro code that does the task YOU want. To me, it is a very smart move to use the hard work of others (who have made this code available to everyone) to get your job done quickly and correctly.

--
Paige Miller
AhmedAl_Attar
Rhodochrosite | Level 12

@Babloo 

Change it to

%let parameter_2=%str(%')%qsysfunc(tranwrd(%superq(parameter),%str(,),%str(%',%')))%str(%');
%put &=parameter_2;

 

Ksharp
Super User
/*Here are two ways:*/
data have;
 set  sashelp.class;
run;

/*First one :*/
%let parameter=Alfred,Mary,Ronald ;

%let want="%sysfunc(tranwrd(%bquote(&parameter.),%str(,),%str(",")))" ;  
%put &=want.;
proc print data=have noobs;
  where name in ( &want. ) ;  
run;


/*Second one */
%let parameter=Alfred,Mary,Ronald ;

proc print data=have noobs;
  where findw("&parameter.",strip(name),',') ;  
run;
Babloo
Rhodochrosite | Level 12

@Ksharp In first solution, can we do it without creating the new macro variable (e.g. want)?  In second solution, how to handle it if we don't know which field from the SAS dataset that macro variable (e.g.  name) values from?

 

Ksharp
Super User

" first solution, can we do it without creating the new macro variable "

Just put it at the position of &want.

/*First one :*/
%let parameter=Alfred,Mary,Ronald ;

proc print data=have noobs;
  where name in ( "%sysfunc(tranwrd(%bquote(&parameter.),%str(,),%str(",")))" ) ;  
run;

 

"how to handle it if we don't know which field from the SAS dataset "

I don't understand, since "name" is already appeared in your PROC PRINT .

Patrick
Opal | Level 21

@Babloo If your source string doesn't contain multibyte characters or single quotes then below should work.

%let parameter=Data Management,Operations,Sales ;

/* construct value for macro variable parameter that includes blanks, a tab and a line feed */
data _null_;
  call symput('parameter',cat('Data','0A'x,'    Management ,  ','09'x,'  Operations , Sales  '));
run;
%put parameter: %nrbquote(&parameter);

data _null_;
  length string $1000;
  /* replace all whitespace characters with a blank */
  string=prxchange('s/\s+/ /',-1,strip("&parameter"));
  /* remove all blanks before or after a comma and add quotes before and after a comma */
  string=prxchange("s/ *(,) */','/",-1,strip(string));
  /* create new macro varialbe, add quotes at the start and end of the string */
  call symputx('parameter_new',cats("'",string,"'"));
run;

%put parameter_new: %nrbquote(&parameter_new);

parameter_new: 'Data Management','Operations','Sales'

Babloo
Rhodochrosite | Level 12

@Patrick  two questions a) How to tweak your solution without creating the new macro variable, 'parameter_new'?  b) In the below code block, you've hardcoded the values but in real life the values of macro variable will change and it can have any special/invisible characters.  

 

%let parameter=Data Management,Operations,Sales ;

/* construct value for macro variable parameter that includes blanks, a tab and a line feed */
data _null_;
  call symput('parameter',cat('Data','0A'x,'    Management ,  ','09'x,'  Operations , Sales  '));
run;

On a separate note, I'd like to know how to handle if we have multibyte characters or single quotes in the macro variable values.

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!
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
  • 48 replies
  • 2144 views
  • 31 likes
  • 11 in conversation