11
votes

As a base SAS programmer, you know the drill:

You submit your SAS code, which contains an unbalanced quote, so now you've got not only and unclosed quote, but also unclosed comments, macro function definitions, and a missing run; or quit; statement.

What's your best trick for not having those unbalanced quotes bother you?

10

10 Answers

8
votes

As for myself, I usually Google for "SAS unbalanced quote", and end up with submitting something like this:

*); */; /*’*/ /*”*/; %mend;

... to break out of unclosed comments, quotes and macro functions.

5
votes

enterprise guide 3 used to put the following line at the top of its automatically generated code:

*';*";*/;run;

however, the only way to really "reset" from all kinds of something unbalanced problems is to quit the sas session, and balance whatever is unbalanced before re-submitting the code. Using this kind of quick (cheap?) hacks does not address the root cause.

by the way, ods _all_ close; closes all the ods destinations, including the default, results destination. in an interactive session, you should open it again with ods results; or ods results on; at least according to the documention. but when i tested it on my 9.2, it did not work, as shown below:

%put sysvlong=&sysvlong sysscpl=&sysscpl;
/* sysvlong=9.02.01M0P020508 sysscpl=X64_VSPRO */

ods _all_ close;
proc print data=sashelp.class;
run;
/* on log
WARNING: No output destinations active.
*/

ods results on;
proc print data=sashelp.class;
run;
/* on log
WARNING: No output destinations active.
*/
5
votes

Here is the one I use.

 ;*';*";*/;quit;run;
 ODS _ALL_ CLOSE;
 QUIT; RUN;
1
votes

I had a situation with unbalanced quotes in a macro and the only solution was to close the instance of SAS and start over.

I feel that's an unacceptable flaw in SAS.

However, I used the methods by BOTH #2 and #5 and it worked. #2 first and then #1. I put them above ALL code, including my code header, explaining what this program was doing.

Worked like a charm.

1
votes

I wrote a perl program that reads through any given SAS program and keeps track of things that should come in pairs. With things like parentheses, which can be embedded, it prints the level of nesting at the beginning of every line. It needs to be able to distinguish parentheses that are part of macro functions from those that are part of data step functions, including %sysfunc calls that reside in the macro environment but make calls to data step functions (must also do similar for %syscall macro function invocations), but that is doable through regular expressions. If the level of nesting goes negative, it is a clue that the problem may be nearby.

It also starts counting single and double quotes from the start of the program and identifies whether the count of each such symbol it encounters is odd or even. As with parentheses, it needs to be able to distinguish quotes that are part of macro code from those that are part of data step code and also those that are part of literal strings such as O'Riley and %nrstr(%'%") and not count them, but pattern matching can handle that too.

If the problem of the mismatched item stems from code that is generated at runtime by macro code and is therefore not present in the source program, then I turn on option mfile to write the generated data step code to a file and then run the perl script against that code.

I chose perl because of its strong pattern-matching capabilities but any other pattern-matching language should work fine. Hope this helps.

1
votes

This works nearly every time for me:

; *'; *"; */;
ODS _ALL_ CLOSE;
quit; run; %MEND;
data _NULL_; putlog "DONE"; run;
0
votes

You could always just issue a terminate submitted statements command and resubmit what you're trying to run.

0
votes

just wanted to reiterate AFHood's suggestion to use the ODS _ALL_ CLOSE; statement. That's a key one to include. And make sure you use it every time you're finished with ODS anyway.

0
votes

Closing the SAS Session worked in my case. I think you can try this once before you try other methods mentioned here.

-1
votes

Yes, I believe the official SAS documentation recommends the solution you have proposed for yourself.