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;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.