SAS Apparent symbolic reference when there is a n ampersand in data - sas

This appears to be an old problem but I haven't seen an answer that fully addresses it. Totally possible I just missed it.
I'm consuming data that has a text field called fullDescription that contains a string like (made up but fits the pattern):
"00001234456 Wells Fargo DR FM AT&T PYMT 00987600"
I'm attempting to parse the data and dig out tidbits like "Wells Fargo" and "AT&T". However, when I manipulate "AT&T" SAS tries to read it as "AT" then the variable value for T. It stopped erroring (but still warns) when I instituted this line:
%LET description = %SYSFUNC(COMPRESS(%BQUOTE(&&fullDescription&row),'',P));
This, at least, returns "00001234456 Wells Fargo DR FM ATT PYMT 00987600" (missing ampersand) but still throws:
WARNING: Apparent symbolic reference T not resolved
I haven't figured out a way to prevent the warning. Is there a way to leave the ampersand in but not treat it as a variable? If that's not possible, can I cleanse it once and not get the error?

You are almost there, just add %nrstr() function when define the macro variable fullDescription.
data _null_;
call symputx('fullDescription','%nrstr(00001234456 Wells Fargo DR FM AT&T PYMT 00987600)');
run;
%LET description = %SYSFUNC(COMPRESS(%bquote(&fullDescription),'',P));
%put &=description;
This makes no warning anymore.

Related

Put with macro variable as format

I have a dataset with a variable called pt with observations 8.1,8.2,8.3 etc and a variable called mean with values like 8.24 8.1 8.234 etc. Which are paired with each other.
I want to be able to set my put informat to the formats from the variable num.
I get the errors "Expecting an arithmetic expression"
"the symbol is not recognized and will be ignored" and "syntax error" from my code. (underlining the &fmt. part)
if pt=&type;
call symput("fmt",pt);
fmt_mean = putn(mean,&fmt.);
Thanks in advance for your help.
The macro processor's work is done before SAS compiles and runs the data step. So trying to place the value into a macro variable and then use it immediately to generate and execute SAS code will not work.
But since you are using the PUTN() function it can use the value of an actual variable, so there is no need to put the format into a macro variable.
fmt_mean = putn(mean,pt);
Please, post your data set and data step. Your description is hard to understand.
However the solution seems to be simple: do not use macro variables! You don't need them here. Unlike put() function which expect format know at compile time (that is when you can use macro variables) its analog putn() expects second argument to be variable. Of course, it works a little slower due to that permittance. So your code can look like that:
data ...;
set ...(keep=mean pt);
fmt_mean = putn(mean, pt);
run;
where pt variable maybe numeric, i.e. 8.2, or character, i.e. '8.2'.
If you want to understand how SAS macro works and what call symput does look here:
https://stackoverflow.com/a/69979074/7864377

SAS Data integration studio

Long time reader first-time questioner.
Using SAS Data Integration studio, when you create a summary transformation in the table options advanced tab you can add a where statement to your code automatically. Unfortunately, it adds some code that makes this resolve incorrectly. Putting the following in the where text box:
TESTFIELD = "TESTVALUE"
creates
%let _INPUT_options = %nrquote(WHERE = %(TESTFIELD = %"TESTVALUE%"%));
In the code, used
proc tabulate data = &_INPUT (&_INPUT_options)
But resolves to
WHERE = (TESTFIELD = "TESTVALUE")
_
22
ERROR: Syntax error while parsing WHERE clause. ERROR 22-322: Syntax
error, expecting one of the following: a name, a quoted string, a
numeric constant, a datetime constant,
a missing value, (, *, +, -, :, INPUT, NOT, PUT, ^, ~.
My question is this: Is there a way to add a function to the where statement box that would allow this quotation mark to be properly added here?
Note that all functions get the preceding % when added to the where statement automatically and I have no control over that. This seems like something that should be relatively easy to fix but I haven't found a simple way yet.
The % are simply escaping the " and () characters; they're perfectly harmless, really. The bigger problem is the %NRQUOTE "quotes" (which are nonprinting characters that tell SAS this is macro-quoted); they mess up the WHERE processing.
Use %UNQUOTE( ... ) to remove these.
Example:
data have;
testfield="TESTVALUE";
output;
testfield="AMBASDF";
output;
run;
%let _INPUT_options = %nrquote(WHERE = %(TESTFIELD = %"TESTVALUE%"%));
%put &=_input_options;
data want;
set have(%unquote(&_INPUT_options.));
run;
Thank you all for your responses. Long story short, I ended up creating a SAS Troubleshooting ticket. The analyst told me that they have now documented the issue, which should now be resolved in a future iteration of DI.
The temporary solution was to create a new transformation, with a slight alteration, adding an UNQOUTE (as mentioned above by Joe) to the source code before the input options:
proc tabulate data = &_INPUT (%unquote(&_INPUT_options)) %unquote(&procOptions);
For those interested you will need to create the transformation in a public subfolder of your project so others can use it. Not what I was hoping for, but a workable solution while waiting for the version update.

SAS new variable name using macro variable

I am trying to create a new variable based on the value of a macro variable. However, SAS highlights 'vari' as red, seemingly indicating that I am doing something wrong. The statement still seems to get executed correctly though. Any thoughts?
%let i=7;
data d1;
set d1;
vari&i=7;
run;
SAS syntax highlighter is an aid, but there are many situations where it is not "correct". Particularly for the macro language, it can't always guess how symbols will resolve. It doesn't have all the information (or intelligence) as the SAS word scanner/tokenizer. I use syntax highlighting as a hint that something might be wrong, but I ignore it when I've checked the code and confirmed it is correct.
The code in your example is fine.

Warn if column is missing in a data step [duplicate]

This question already has an answer here:
Can I Promote Notes About Uninitialized Variables to Errors
(1 answer)
Closed 7 years ago.
I had a recent problem where I was using a data step to create an output file and one of the columns had been renamed. The data step executed normally filling in the now missing column with nulls without any errors or warnings. It did add a note in the log saying that a variable was undefined but otherwise there was no indication that anything was wrong.
Is there anyway to force the data step to error out or at least give a more noticeable warning in such a situation?
There is an undocumented system option which turns problematic notes into errors, including the uninitialized note. I find it very handy.
1 options dsoptions=note2err;
2 data a;
3 y=x;
4 run;
ERROR: Variable x is uninitialized.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.A may be incomplete. When this step was stopped there were 0 observations and 2 variables.
Put a list of the expected variables in the output file in a keep statement in your data step (or a keep= clause on the output dataset), and set option dkrocond = error; before running your data step. This is quite an old option (it goes back to at least SAS 9.1.3) so it should work in your scenario.
You can also trigger similar error messages if variables are missing from an input dataset by setting option dkricond = error;.
You can also set either of these to warn if you prefer.
Also, if you want a more general method of detecting whether a variable is present in a data set, you could try something like this:
data _null_;
dsid = open('sashelp.class');
vnum1 = varnum(dsid,'varname');
vnum2 = varnum(dsid,'sex');
rc = close(dsid);
put vnum1= vnum2=;
run;
The crucial behaviour here is that the varnum function returns 0 for variables that are not present in the opened dataset. All of the functions used above can be used with %sysfunc, so it's even possible to do this sort of check in pure macro code, i.e. without actually running a data step or proc.

How to clear session of open error

When working is the base sas client, if a user accidentially forgets a parathesis, quote, semi-colon, or end-comment that will sometimes cause any additional code they try running to fail. If I'm trying to help someone experiencing one of these errors, how can I clear the current buffer and start fresh without opening a brand new session?
I've always used the one documented on support.sas.com
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a001302436.htm
*'; *"; *); */; %mend; run;
Submit that until you get the log message :
ERROR: No matching %MACRO statement for this %MEND statement.
There is no true best way, as it depends on too many things. Presumably the user will know what might have gone wrong, and can use that information; for example, are we possibly missing a %mend somewhere that caused us to get locked into a macro?
The EG method is one of the better ones. At the start of every EG process (ie, every time you hit 'Run' on a program or section of program), it runs:
;*';*";*/;quit;run;
That:
Semicolon ends any statement that hadn't ended
Comment singlequote, and comment doublequote, end any trailing quotes (both trailed by ; )
Star slash ends any block comments
Quit and run end any procedures that had been left open.
EG doesn't include %mend; because it would generate a warning, but you could include that if you didn't mind the warning and wanted to catch one of the common issues. If you do include it, put it up front - macros will not properly deal with those hanging quotes, and you need to be out of them for sure first.