2009-03-05 2 views
3

Есть ли короткий способ сделать ВСЕ макропеременные, созданные внутри макроса глобального масштаба?SAS Macro GLOBAL scope

т.е.

%macro x; 
%global _all_; * ??? ; 
%let x=1; 
%let y=1; 
%let z=1; 
%mend; 
+3

Вы действительно хотите это сделать? Вы можете клонировать уже существующие глобальные макропеременные с вашими локальными. И вы просите способ сделать это неявно! Рекомендуемая практика - объявить% LOCAL (никогда% GLOBAL) всех переменных, которые вы используете в макросе. –

+3

Я абсолютно согласен с Chang Chung. Вы можете легко вызвать проблемы для себя или других, если вы сделаете это стандартной практикой. Если вам абсолютно необходимо это сделать, попробуйте убедиться, что они названы с использованием префикса, чтобы они не были перезаписаны случайно. –

ответ

5

Единственный способ, которым я могу думать, чтобы сделать это без того, чтобы объявить каждый макрос как глобальный загодя, а затем сделать% пусть заявление является для использования макроса вместо Утверждение% let.

В приведенном ниже коде я создаю макрос с именем % mylet, который имеет своей единственной целью задачу создания глобальной переменной с именем и значением, которое передается в качестве аргументов. Затем я использую этот макрос вместо% let везде, где мне нужны глобальные переменные.

например.

%global myvar; 
%let myvar=2; 

стал бы ...

%mylet(myvar,2);

/* Define a macro to declare variables as global */ 
%macro mylet(var,value); 
    %global &var; 
    %let &var.= &value ; 
%mend; 

/* Test macro */ 
%macro test; 
%mylet(myvar,2); 
%mylet(myvar2,12); 
%mylet(myvar3,'string'); 

/* see that they are global inside the macro */ 
title "Macro scope inside test macro"; 
proc sql; 
    select * 
     from dictionary.macros 
     where name in('MYVAR','MYVAR2','MYVAR3'); 
quit; 

%mend; 
%test; 

/* Check to see if they are still global outside the macro */ 
title "Macro scope outside test macro"; 
proc sql; 
    select * 
     from dictionary.macros 
     where name in('MYVAR','MYVAR2','MYVAR3'); 
quit; 
+0

Вместо того, чтобы запрашивать словарные таблицы, вы можете просто: % положить _global_; или% put _local_; для просмотра списка глобальных и локальных макросов (и их значений). Вы также можете сделать% put _user_; для просмотра только определенных пользователем макросов (и значений). –

+1

Очень верно. Я решил использовать таблицу словаря в этом случае, поскольку я обнаружил, что люди менее знакомы с этими таблицами, и я надеялся, что это может дать другим новые вещи для изучения. Также он позволил мне легко изолировать три переменные на выходе независимо от того, какие другие переменные были определены. – cmjohns

4

При создании макропеременной в пределах открытого кода переменная макросы автоматически будут добавлены в глобальном макро таблицы символов:

%let x=1; 
%let y=1; 
%let z=1; 

Это было бы перед тем вы создать крупный макрос:

%macro x; 
    <code here> 
%mend x; 

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

data _null_; 
    set LIB.DSET; 
    x = 1; 
    call symput('x',x); 
run; 
+1

Использование 'call symputx()' с параметром '' g'' было бы лучшим подходом. –

3

Если вы создаете макропеременные в пределах данных шага, и что данные шаг внутри макроса, то создаваемые макрокоманды будут по умолчанию локальными по объему для этого макроса.

Использование

call symputx('macvar',macval,'g'); 

для создания глобальных переменных макросов.

+0

Действительно ли это так? Можете ли вы предоставить код, чтобы доказать это? –