SAS:Вызов одного макроса из другого…Порядок определений макросов

StackOverflow https://stackoverflow.com/questions/537283

  •  22-08-2019
  •  | 
  •  

Вопрос

В моем коде у меня есть несколько макросов.Макрос A - это основной макрос.Затем макрос A вызывает макрос B, который, в свою очередь, вызывает макрос C.

В SAS, должен ли я определять их в обратном порядке?Другими словами, должен ли я сначала определить макрос C, затем макрос B, затем макрос A в последнюю очередь?Или это имеет значение, поскольку SAS считывает весь код до того, как он фактически попадет в команду для запуска макросов?Если уж на то пошло, могу ли я выдать команду для запуска макроса в качестве первого оператора в моем коде, а затем определить макросы под командой?

Спасибо!

Это было полезно?

Решение

Во-первых, вы должны определить макрос до его вызова.

Во-вторых, не имеет значения, где вызывается макрос, если вы загрузили его заранее.

Чтобы подробнее остановиться на вашей проблеме:Библиотека автозвонков - ваш друг.Если администратор SAS не разрешает вам помещать ваши макросы в библиотеку автозвонков, вы можете добавить автозвон следующим образом:

filename mymacros 'c:\mysas'; 
/*this defines the directory you have stored your macros*/

options sasautos=(sasautos mymacros) mautosource; 

Другие советы

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

%macro a;
  %put a;
  %b
%mend a;

%macro b;
  %put b;
  %c
%mend b;

%macro c;
  %put c;
%mend c;

%*-- %a is main --*;
%a
/* on log
a
b
c
*/

Вы должны определить макрос до его вызова, поэтому строка с "%A" должна следовать определению макроса A.Порядок других макроопределений не имеет значения, при условии, что они определены до их вызова.Обычно в своих программах я настраиваю основной макрос, как вы описали, затем последняя строка программы вызывает этот макрос.

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

В SAS необходимо определить два аспекта кода макрокоманды:код макроса, который компилируется, и параметры макроса:

Код макроса:

Сам код макроса очень прост в том смысле, что когда %macro обнаружен токен, система SAS начинает компилировать макрос SAS и продолжает компилировать до тех пор, пока он не достигнет %mend жетон.Единственные реальные проблемы, с которыми вы можете столкнуться, – это если вы обновили код макроса и не перекомпилировали его перед выполнением - в этих ситуациях он по-прежнему будет запускать старую версию, имеющуюся в библиотеке макросов.По расширению, если вы попытаетесь скомпилировать макрос, который вызывает другой макрос, который еще не был определен, вы получите сообщение об ошибке.По этим причинам их необходимо программировать в том порядке, в котором они вызываются (как показано в примере ниже:%level3 предшествует %level2, который предшествует %level1)

Макропеременные: При определении макроса переменные есть две области применения:Глобальный и локальный.После определения глобальные переменные могут быть доступны в любом месте и в любое время.Однако локальные переменные существуют только локально во время выполнения макроса, в котором он был определен.Дополнительно, если макрос, в котором была определена локальная переменная, вызывает любые другие макросы, локальная переменная макроса все равно будет доступна:

Рабочий пример:

В следующем примере макросы являются определяется в обратном порядке чтобы предотвратить возврат SAS Очевидный вызов макроса предупреждение.

Приведенная ниже диаграмма иллюстрирует структуру следующих макросов в следующем примере:

|-----------------------------|
|GLOBAL                       |
|  |------------------------| |
|  |LEVEL1                  | |
|  |  |-------------------| | |
|  |  |LEVEL2             | | |
|  |  |  |--------------| | | |
|  |  |  |  LEVEL3      | | | |
|  |  |  |--------------| | | |
|  |  |-------------------| | |
|  |------------------------| |
|-----------------------------|

Скомпилируйте вложенные макросы:

 %macro level3 ;
  %put **** START LEVEL3 **** ;
  %local G1;
  %let G1=Local ;

  %do i=1 %to 2 ;
    %put In the macro do loop I=&i ;
  %end ;

  %put The value of I at level3 is: &I ;
  %put Are we accessing global or local G1 variable here: &G1 ;

  %put **** END LEVEL3 ****;
%mend level3 ;


 %macro level2 ;
  %put **** START LEVEL2 **** ;
  %*global L1 ; *<-- this would produce an error because the variable name has already been added to the local scope in %level1 ;

  %put Are we accessing global or local G1 variable here: &G1 ;
  %put Can we access local variables here: &L1 ;

  %level3 ;

  %put The value of I in level2 is: &I ;
  %put **** END LEVEL2 ****;
%mend level2 ;

Скомпилируйте макрос верхнего уровня (который, в свою очередь, вызывает два вышеупомянутых макроса) и запустите его:

%let G1=Global;
%macro level1 ;
  %put **** START LEVEL1 **** ;
  %let L1=Yes;

  %put Are we accessing global or local G1 variable here: &G1 ;
  %put Can we access local variables here: &L1 ;

  %level2 ;

  %put The value of I outside of the local macro is: &I ;
  %put Are we accessing global or local G1 variable here: &G1 ;

  %put **** END LEVEL1 ****;
%mend level1 ;
%level1 ;

Моменты, на которые следует обратить внимание при просмотре журнала:

  • За %как Level3, и возвращает предупреждение о том, что переменная макроса не существует
  • В %level3 при вызове &G1 возвращается значение, сохраненное в локальной области %level3.После выхода за пределы %level3 значение возвращается к значению, сохраненному глобально
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top