在 BASE SAS 中打破不平衡报价条件的最佳技巧是什么?

发布于 2024-07-05 22:30:56 字数 151 浏览 7 评论 0原文

作为一名基础 SAS 程序员,您知道该怎么做:

您提交 SAS 代码,其中包含不平衡的引用,因此现在您不仅拥有未关闭的引用,而且还拥有未关闭的注释、宏函数定义和缺失的运行; 或退出; 陈述。

为了不让那些不平衡的报价困扰你,你最好的技巧是什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

薄荷港 2024-07-12 22:30:57

是的,我相信 SAS 官方文档推荐了您为自己提出的解决方案。

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

つ可否回来 2024-07-12 22:30:57

关闭 SAS 会话对我来说是有效的。 我认为您可以先尝试一次,然后再尝试这里提到的其他方法。

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

婴鹅 2024-07-12 22:30:56

我遇到了宏中报价不平衡的情况,唯一的解决方案是关闭 SAS 实例并重新开始。

我认为这是 SAS 的一个不可接受的缺陷。

不过,我使用了 #2 和 #5 的方法并且有效。 先#2,然后#1。 我把它们放在所有代码之上,包括我的代码头,解释这个程序在做什么。

工作起来就像一个魅力。

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.

岛徒 2024-07-12 22:30:56

这是我用的。

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

Here is the one I use.

 ;*';*";*/;quit;run;
 ODS _ALL_ CLOSE;
 QUIT; RUN;
揽月 2024-07-12 22:30:56

至于我自己,我通常Google 搜索“SAS 不平衡报价”,最终提交类似 this

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

...打破未封闭的评论、引用和宏函数。

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.

温柔嚣张 2024-07-12 22:30:56

企业指南 3 过去常常将以下行放在其自动生成的代码的顶部:

*';*";*/;run;

但是,真正从各种不平衡问题中“重置”的唯一方法是退出 sas 会话,并在重新平衡之前平衡任何不平衡的内容提交代码。 使用这种快速(便宜?)的黑客方法并不能解决根本原因。

顺便说一下,ods _all_ close; 关闭所有 ods 目标,包括默认的结果目标。 在交互式会话中,您应该至少根据文档使用 ods results;ods results on; 再次打开它。 但是当我在我的9.2上测试时,它不起作用,如下图:

%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.
*/

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.
*/
放手` 2024-07-12 22:30:56

我编写了一个 Perl 程序,它可以读取任何给定的 SAS 程序并跟踪应该成对出现的内容。 使用可以嵌入的括号之类的东西,它可以在每行的开头打印嵌套级别。 它需要能够区分属于宏函数的括号和属于数据步骤函数的括号,包括驻留在宏环境中但调用数据步骤函数的 %sysfunc 调用(也必须对 %syscall 宏执行类似的操作)函数调用),但这可以通过正则表达式实现。 如果嵌套级别变为负值,则表明问题可能就在附近。

它还从程序开始时开始计算单引号和双引号,并确定遇到的每个此类符号的计数是奇数还是偶数。 与括号一样,它需要能够区分属于宏代码的引号、属于数据步骤代码的引号以及属于文字字符串的引号,例如 O'Riley 和 %nrstr(%'%")并且不计算它们,但模式匹配也可以处理这个问题。

如果不匹配项的问题源于宏代码在运行时生成的代码,因此不存在于源程序中,那么我打开选项 mfile 来编写将生成的数据步骤代码保存到文件中,然后针对该代码运行 perl 脚本,

因为它具有强大的模式匹配功能,但任何其他模式匹配语言都应该可以正常工作。

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.

旧城空念 2024-07-12 22:30:56

只是想重申 AFHood 使用 ODS _ALL_ CLOSE; 语句的建议。 这是要包括在内的一个关键因素。 无论如何,请确保每次使用完 ODS 后都使用它。

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.

孤蝉 2024-07-12 22:30:56

您始终可以发出终止提交的语句命令并重新提交您尝试运行的内容。

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

紫竹語嫣☆ 2024-07-12 22:30:56

这对我来说几乎每次都有效:

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

This works nearly every time for me:

; *'; *"; */;
ODS _ALL_ CLOSE;
quit; run; %MEND;
data _NULL_; putlog "DONE"; run;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文