0

我有一个固执的讲师,他坚持要像这样在宏语句的括号内定义所有宏变量

%MACRO TEST(Var1= , Var2= , Var3= );

这样做有什么好处?像这样实际定义函数有什么好处:

%LET var1= <Insert long list of 50 variables here>;
%LET var2= <name of input data>;
%LET var3= <group by variables>;

%MACRO TEST;

我认为第二个选项提供了清晰和整洁的编码结构,有人能指出这两种方法的任何其他优点或缺点吗?

4

4 回答 4

4

两个要点:

  • 使用全局变量被广泛认为是不好的做法
  • 使用您的系统,您将如何在代码的不同位置编写对同一宏的多个调用?您将如何跟踪哪些参数列表对应于哪些宏调用?
于 2018-11-12T12:16:21.373 回答
1
  1. 宏变量范围 - 仅在宏中使用变量可确保不会意外使用任何先前声明的宏变量。如果你不小心把事情搞砸了,你的方法很可能会遇到问题。
  2. 它清楚地说明了宏需要哪些参数 - 否则您必须阅读代码,找到所有 & 并在顶部声明它们。
  3. 整体打字少
  4. 您可以在参数列表中设置默认值,然后在声明时仅列出/调用您需要的选项。

宏定义:

%macro test(var1 = , var2 = , var3 = 25);

宏调用/执行:

%test(var1 = 5, var2 = 4);

var3 在宏中会有什么值?

  1. 您仍在使用非常简单的案例,并且当您有参数时,许多更复杂的用法会更好地工作。考虑为碰巧在数据集中的不同参数调用相同宏 50 次的情况。您可以对每个使用 CALL SYMPUTX() ,但随后会遇到调用宏等的时间问题。而使用 CALL EXECUTE 和内联参数使其非常容易。

PS。一般来说,当你刚开始的时候,你的讲师有 99% 的几率是正确的。假设这将帮助您以不同的方式构建您的问题,而不是试图证明某人是错误的(这就是您的问题的方式),您将着眼于了解事物的工作原理。此外,您的讲师也可能会在线,因此如果他们在某个时候看到您的问题,您就不会被认为是一个无所不知的孩子。最终那是你的选择。

于 2018-11-12T20:27:47.203 回答
0

这取决于如何使用宏。全局宏非常有用,正如您所指出的,如果正确使用它们,它们会提供清晰的信息。例如,如果我有一堆 SAS 程序需要运行以生成数据集或报告,我会将它们放在包装程序中并使用全局宏。

%Let year = 2019;
%Let State = CA;
%let Dept = DOE;

%macro MakeRpt;

%include "MakeData.sas";
.
. more %include statements
.
%include "GenerateReport.sas";

%mend;

%makeRpt;

但是,如果我正在制作一个用户需要时调用的宏“实用程序”,那么使用本地宏是最有意义的。这实际上是一个如何使用宏来决定全局还是局部更有意义的问题。

于 2018-11-12T14:47:20.147 回答
0

唯一一次你想要这样做是如果你有将出现在整个程序中的全局变量。例如,使用特殊的设置或初始化程序来保存常用值的情况并不少见,尤其是在开发和生产之间进行时。这可以在推广程序时使事情变得更容易处理,或者如果稍后某些事情发生变化(例如目录位置或主机名),则更容易调整。

例如,下面的宏可以更改一些全局宏变量以指向在两个服务器之间不同的某些目录,具体取决于代码运行的位置。

%macro dev_prod;
    %global directory inlib outlib;

    %if(&syshostname. = production-server.company.com) %then %do;
        %let directory = C:\prodlocation;
        %let inlib     = C:\prodlib;
        %let outlib    = C:\outlib;
    %end;
        %else %if(&syshostname. = dev-server.company.com) %then %do;
            %let directory = C:\devlocation;
            %let inlib     = C:\devlib;
            %let outlib    = C:\outlib;
        %end;
%mend;
%dev_prod;

通常,您希望在执行特定功能的宏中使用局部宏变量。例如,以下宏对数据集上的变量进行回归:

%macro regression(data=, dep=, indep=);
    proc reg data=&data.;
        model  &dep. = &indep.;
    run;
%mend;
%regression(data=sashelp.cars, dep=horsepower, indep=msrp); 
于 2018-11-12T20:58:31.910 回答