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;
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.
Ready to level-up your skills? Choose your own adventure.