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

If the value of the macro variable have spaces then the following code is throwing the syntax error. Code and log is shown below. Any help to resolve the issue?

 

Value of macro variable 'parameter_2' resolves to 'Data Management'

 

Program:

 

proc print data=sorted_nodup noobs;
where &parameter_1 IN("&parameter_2");
var &_field;
run;

data _null_;
test = '/'||&parameter_2||'/';
put test=;
run;

Log:

12   proc print data=sorted_nodup noobs;
13   where &parameter_1 IN("&parameter_2");
14   var &_field;
15   run;

NOTE: There were 194 observations read from the data set WORK.SORTED_NODUP.
      WHERE DIVISION='Data Management';
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds
      

16   
17   data _null_;
18   test = '/'||&parameter_2||'/';
NOTE: Line generated by the macro variable "PARAMETER_2".
18   Data Management
            ----------
            22
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, *, **, +, -, /, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT, 
              LE, LT, MAX, MIN, NE, NG, NL, OR, [, ^=, {, |, ||, ~=.  

19   put test=;
20   run;
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

@Babloo wrote:

@Tom  Parameter_2 will have either one value or more than values.  If we have one value, I want to execute,

 

test = '/'||"&parameter_2" ||'/'; 

If we have more than one values then I want to execute in the same data_null_ step. 

 

test =cats( '/', catx('/',&parameter_2) , '/');

Any help?


The second option should generate the same string when there is one value as the first one.  That is the nature of the CATX() function, when there is only one value no delimiter is added.

 

Show actual examples of values the macro variable PARAMETER_2 can have and what actual output you want for those inputs.

 

View solution in original post

11 REPLIES 11
ballardw
Super User

You might share the purpose of this code and the way that you actually define the macro variables.

 

Lets look at this line of code:

test = '/'||&parameter_2||'/';

If &parameter_2 has been defined to be the characters ABC then the above becomes

test = '/'||ABC||'/';

Which treats ABC as an undefined variable. Test it. The log will show something like

31   data _null_;
32   test = '/'||ABC||'/';
33   put test=;
34   run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      32:13
NOTE: Variable ABC is uninitialized.
test=/           ./

One important bit is the uninitialized. Note that it is referring to a VARIABLE, not text, but a variable. Then since the variable was not previously defined SAS assumes it is numeric. Since you are using the variable, which has no value assigned, in a Character expression you get the "Numeric values have been converted" note. This is typically not a good thing. SAS then uses its internal default rules to convert the value to character which is to use a BEST12 format. Which results in 11 spaces and the default period for missing values.

If the macro variable has value like "Data management", two words separated by a space the code becomes

data _null_;
test = '/'||Data management||'/';
put test=;
run;

Do you see the problem? You now have TWO undefined variable with a space between them. Since the concatenation operator || does not allow a space delimited list of variables then you get an error, which mainly means "SAS expected some sort of operation appropriate to two numeric variables, hence all of those numeric operators in the error message.

 

I suspect that you want quotes around the value of the macro variable but without knowing exactly what text you expect to create I'm not sure.

 

So, show the code that worked without any macro variables and a working Where statement with two or more words in the IN part.

 

Please, always include how the macro variables are defined and values for all macro variables.

 

Instead of very ugly code with || everywhere you may want to consider use of the CATT or CATS concatenation such as

test =cats( '/',"&parameter_2",'/')

Cats removes leading and trailing blanks from the parameters, CATT only removes the trailing blanks.

Without knowing why you wrote that data _null_ step you might also consider if the purpose was just to see the macro value surrounded by some character to tell where it starts and ends.

test = quote("&parameter_2");

 

Babloo
Rhodochrosite | Level 12

@ballardw what would be the correct solution for the error? As you gave two solutions, one with quote function and the other with CATS function which one to consider? How to combine these two functions into one line and use it in my data _null_?

ballardw
Super User

@Babloo wrote:

@ballardw what would be the correct solution for the error? As you gave two solutions, one with quote function and the other with CATS function which one to consider? How to combine these two functions into one line and use it in my data _null_?


I have no idea what the "correct solution" would be as I do not know the purpose of that data _null_ step. You have to show what you expect the code generated by the macro to be.

Babloo
Rhodochrosite | Level 12

@ballardw Should I try like this?

 

data _null_;
test =cats( '/',"&parameter_2",'/')
put test=;
run;
Quentin
Super User

@Babloo wrote:

@ballardw Should I try like this?ing 

The answer to "should I try it" is always yes. Well, as close to "always" as you can get.

 

Especially when trying it is easy, with code like:

 

%let parameter_2= Data Management ;

data _null_;
  test =cats( '/',"&parameter_2",'/') ;
  put test=;
run;

data _null_;
  test =cats( '/',&parameter_2,'/') ;
  put test=;
run;
BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Tom
Super User Tom
Super User

Why are you using the IN operator when your code only supports a single value?

proc print data=sorted_nodup noobs;
  where &parameter_1 = "&parameter_2" ;
  var &_field;
run;

data _null_;
  test = '/' || "&parameter_2" || '/';
  put test=;
run;

If you want to support multiple values I would suggest putting the quotes into the value of the macro variable.

%let paramter_2="Data Management","Operations","Sales" ;

Then your code might look like:

proc print data=sorted_nodup noobs;
  where &parameter_1 in ( &parameter_2 ) ;
  var &_field;
run;

data _null_;
  test = cats( '/', catx('/',&parameter_2) , '/');
  put test=;
run;

To generate TEST with a value like

/Data Management/Operations/Sales/

Babloo
Rhodochrosite | Level 12

@Tom  Parameter_2 will have either one value or more than values.  If we have one value, I want to execute,

 

test = '/'||"&parameter_2" ||'/'; 

If we have more than one values then I want to execute in the same data_null_ step. 

 

test =cats( '/', catx('/',&parameter_2) , '/');

Any help?

Tom
Super User Tom
Super User

@Babloo wrote:

@Tom  Parameter_2 will have either one value or more than values.  If we have one value, I want to execute,

 

test = '/'||"&parameter_2" ||'/'; 

If we have more than one values then I want to execute in the same data_null_ step. 

 

test =cats( '/', catx('/',&parameter_2) , '/');

Any help?


The second option should generate the same string when there is one value as the first one.  That is the nature of the CATX() function, when there is only one value no delimiter is added.

 

Show actual examples of values the macro variable PARAMETER_2 can have and what actual output you want for those inputs.

 

Babloo
Rhodochrosite | Level 12

 If I add double quotes in parameter_2 in CATX argument, it seem to be working fine.  Is it correct to add double quotes as shown below?

 

test =cats( '/', catx('/',"&parameter_2") , '/'); 
Tom
Super User Tom
Super User

Unless PARAMETER_2 has something really strange in it then there is no need for the CATX() function call in that case.

test =cats( '/', "&parameter_2" , '/'); 

The only way the other makes any sense if it you created PARAMTER_2 with text like:

name1","name2","name3

Which is just goofy looking and likely to cause you trouble with unbalanced quotes.

Babloo
Rhodochrosite | Level 12

@Tom  I agree with you. As it seem to working fine after I added double quotes , do you see any harm in later stage?

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
  • 719 views
  • 5 likes
  • 4 in conversation