I have the following code in my program and it is returning the value of '%%' (the else condition) when it should be returning the value of '%'. What am I doing wrong?
%LET TYPE_CD = %; %macro TYPECD; %if &TYPE_CD = '%' %then call symput("NEW_TYPE_CD","'"||"&TYPE_CD"||"'"); /*leave variable as is*/ %else call symput("NEW_TYPE_CD","'"||"&TYPE_CD"||"%'"); /wrap with % %mend TYPECD;
NEW_TYPE_CD is returning value of '%%', should be '%'
TYPE_CD is defined in SMC as a prompt with default value of '%'
If user leaves default, I want to select all type codes, so format is '%'.
If user enters '722', I want to format as '722%' to select all type_cds that begin with '722'.
I am trying to assign these values in the macro.
Yes, you have to remember that the macro pre-processor is basically an advanced text find/replace. So take your code and resolve it yourself, it looks like:
data _null_; /* build new prompt columns to use wildcard */ if % = '%' then call symput('NEW_NAICS_CD',"'"||"%"||"'"); else call symput('NEW_NAICS_CD',"'"||"%"||"%'"); RUN;
Maybe post an example of what you have and what you want, as from your code it looks like you want the text from &NAIS_CD followed by %, so something like:
data _null_; if strip("&NAICS_CD.")='%' then call symput('NEW_NAICS_CD',"'%'"); else call symput('NEW_NAICS_CD',cats("'","&NAICS_CD","%'"); run;
Now if &NAIS_CD. resolves to %, then &NEW_NAICS_CD. will resolve to '%' otherwise it will resolve to the text in &NAICS_CD. with the text % in single quotes (so for example if ABC: 'ABC%').
This if fails:
%if &TYPE_CD = '%' %then
as: if % = '%' is not true.
Then this gets called:
%else call symput("NEW_TYPE_CD","'"||"&TYPE_CD"||"%'");
becomes:
else call symput("NEW_TYPE_CD","'"||"%"||"%'");
As you have the macro parameter between double quotes, i.e. it dereferences at that point.
Personally I wouldn't do this this way at all, what is the problem with using basic datastep code?
I had the following in a data step first and got errors on this as well. I changed it to use a macro to see if I could get it to work. I agree that data step is best way... just couldn't get it to work. As you can tell, I do not have a lot of experience with SAS code.
Here is what I had in Data step:
data _null_; /* build new prompt columns to use wildcard */ if &NAICS_CD = '%' then call symput('NEW_NAICS_CD',"'"||"&NAICS_CD"||"'"); else call symput('NEW_NAICS_CD',"'"||"&NAICS_CD"||"%'"); RUN;
The error says:
59 data _null_;
60 /* build new prompt columns to use wildcard */
61 if &NAICS_CD = '%' then call symput('NEW_NAICS_CD',"'"||"&NAICS_CD"||"'");
____
180
ERROR: Undeclared array referenced: symput.
61 if &NAICS_CD = '%' then call symput('NEW_NAICS_CD',"'"||"&NAICS_CD"||"'");
_
22
ERROR 180-322: Statement is not valid or it is used out of proper order.
ERROR 22-322: Syntax error, expecting one of the following: +, =.
What does &NAICS_CD resoves to?
Use OPTIONS SYMBOLGEN;
Hello @ncsthbell,
Just use the single quotes only where you need them.
If TYPE_CD (or NAICS_CD, resp.) typically contains a percent sign without single quotes, then the %IF condition in your macro should read &TYPE_CD=%. There is no need for additional quotes, because in macro language text processing is the default.
In the data step, however, you should write the condition as "&TYPE_CD"="%" (or equivalently "&TYPE_CD"='%'), because a "naked" percent sign is not an appropriate character value in a data step.
Currently you add single quotes (and, in the %ELSE/ELSE branch, an additional percent sign) to whatever TYPE_CD (or NAICS_CD) contains. So, you would not "leave variable as is."
Yes, you have to remember that the macro pre-processor is basically an advanced text find/replace. So take your code and resolve it yourself, it looks like:
data _null_; /* build new prompt columns to use wildcard */ if % = '%' then call symput('NEW_NAICS_CD',"'"||"%"||"'"); else call symput('NEW_NAICS_CD',"'"||"%"||"%'"); RUN;
Maybe post an example of what you have and what you want, as from your code it looks like you want the text from &NAIS_CD followed by %, so something like:
data _null_; if strip("&NAICS_CD.")='%' then call symput('NEW_NAICS_CD',"'%'"); else call symput('NEW_NAICS_CD',cats("'","&NAICS_CD","%'"); run;
Now if &NAIS_CD. resolves to %, then &NEW_NAICS_CD. will resolve to '%' otherwise it will resolve to the text in &NAICS_CD. with the text % in single quotes (so for example if ABC: 'ABC%').
Thanks so much RW9.... your example was exactly what I needed it to do!
You will find it much easier to not use % in that way in your input macro variables. Since % is a macro trigger it can cause trouble.
Why not just tell the users to use *, which is not a macro trigger, and then when you generate the value that you want to use in your LIKE condition you can replace the * with %.
data _null_;
call symputx('new_type_cd',catq('1at',translate(symget('type_cd','%','*')));
run;
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.
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.