Преимущества определения макропеременных вне макрофункции - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть упрямый лектор, который настаивает на том, чтобы определить все макропеременные в скобках оператора макроса, как это

%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 ]

0 голосов
/ 12 ноября 2018

Единственный раз, когда вы захотите это сделать, - это если у вас есть глобальные переменные, которые появятся в программе. Например, нередко иметь специальные программы установки или инициализации для хранения часто используемых значений, особенно при переходе от разработки к производству. Это может упростить обработку при продвижении программы или настроить, если в дальнейшем некоторые вещи изменятся (например, местоположение каталога или имя хоста).

Например, приведенный ниже макрос может изменить некоторые глобальные макропеременные, чтобы они указывали на определенные каталоги, которые различаются между двумя серверами в зависимости от того, где выполняется код.

%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); 
0 голосов
/ 12 ноября 2018

Зависит от того, как будут использоваться макросы. Глобальные макросы могут быть очень полезны и, как вы указали, обеспечивают ясность, если они используются правильно. Например, если у меня есть несколько программ SAS, которые необходимо запустить для создания наборов данных или отчетов, я бы поместил их в программу-оболочку и использовал глобальные макросы.

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

%macro MakeRpt;

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

%mend;

%makeRpt;

Однако, если я создаю макрос «утилита», которая будет вызываться пользователем всякий раз, когда ему это нужно, использование локальных макросов имеет смысл. Это действительно вопрос о том, как макрос будет использоваться в отношении того, имеет ли смысл глобальный или локальный.

0 голосов
/ 12 ноября 2018
  1. Область действия макропеременной - наличие переменных, доступных только внутри макроса, гарантирует, что любые ранее объявленные макропеременные не использовались случайно. Если вы случайно вышли из строя, с вашим методом вы можете столкнуться с проблемами.
  2. Он дает понять, какие параметры требует макрос - в противном случае вы должны прочитать код, найти все символы & и объявить их в верхней части.
  3. Меньше общего набора текста
  4. Вы можете установить значения по умолчанию в списке параметров, а затем только перечислить / вызвать те опции, которые вам нужны при объявлении.

Определение макроса:

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

Вызов / выполнение макроса:

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

Какое значение будет иметь var3 в макросе?

  1. Вы по-прежнему используете очень простые случаи, и многие более сложные способы использования работают лучше, когда у вас есть параметры. Рассмотрим случай с вызовом одного и того же макроса 50 раз для разных параметров, которые находятся в наборе данных. Вы можете использовать CALL SYMPUTX () для каждого, но тогда у вас возникнут проблемы с синхронизацией при вызове макроса и тому подобное. В то время как использование CALL EXECUTE и встроенных параметров делает это очень простым.

PS. В целом, шансы 99%, что ваш лектор будет прав в данный момент, когда вы начинаете. Предполагая, что это поможет вам сформулировать свои вопросы по-другому, вместо того, чтобы пытаться доказать, что кто-то не прав (именно так ваш вопрос встречается), вы будете смотреть на понимание того, как что-то работает. Кроме того, возможно, что ваш лектор также будет в сети, поэтому, если они в какой-то момент увидят ваши вопросы, вы не станете всезнайкой. В конечном счете, это ваш выбор.

0 голосов
/ 12 ноября 2018

Два основных момента:

  • Использование глобальных переменных широко считается плохой практикой .
  • Используя вашу систему, как бы вы записали несколько вызовов одного и того же макроса в разных местах вашего кода? Как вы будете отслеживать, какие списки параметров соответствуют каким вызовам макросов?
...