2015-06-15 27 views
7

Makro değişkenini makro içinde tanımlıyorum. Sonra onu ikinci bir makroya besliyorum. Makro 2 sayacı 200 değerini değiştirir. Ancak, makro 2 çalıştırdıktan sonra koyduğum makro değişkeninin içinde ne olduğunu kontrol ettiğimde, hala 0 diyor. 200 değerini saklamak isterim? Mümkün mü?Makro Değişkeninin SAS Makro İçindeki Değişen Değeri

%macro macro1(); 
    %let variable1= 0; 
    macro2(counter=&variable1) 

    %put &variable1; 
%mend macro1; 

%macro1; 

cevap

9

Burada birkaç sorun var. Her şeyden önce, macro2 aramanızdan önce % eksik, ancak bu sadece bir yazım hatası var. Ana konu, diğer dillerde call-by-reference olarak adlandırılan şeyi yapmaya çalıştığınızdır. Bunu SAS makrosunda değişkeninizin yerine değişkeninizin değeri yerine adını geçirerek yapabilir ve sonra bu ismin değişkeni yeni bir değere ayarlamak için bazı funky & sözdizimini kullanabilirsiniz. İşte

yapar örnek kod:

%macro macro2(counter_name); 
    /* The following code translates to: 
    "Let the variable whose name is stored in counter_name equal 
    the value of the variable whose name is stored in counter_name 
    plus 1." */ 

    %LET &counter_name = %EVAL (&&&counter_name + 1); 

%mend; 

%macro macro1(); 
    %let variable1= 0; 

    /* Try it once - see a 1 */ 
    /* Notice how we're passing 'variable1', not '&variable1' */ 
    %macro2(counter_name = variable1) 
    %put &variable1; 

    /* Try it twice - see a 2 */ 
    /* Notice how we're passing 'variable1', not '&variable1' */ 
    %macro2(counter_name = variable1) 
    %put &variable1; 
%mend macro1; 

%macro1; 

Aslında &&& sözdizimi bir açıklaması var StackOverflow'daki başka yazı var; have a look at it here yapabilirsiniz. %EVAL aramasının, referans ile hiçbir ilgisi olmadığını unutmayın, sadece ekleme yapmak için oradadır.

+1

Teşekkürler, dikkat çekildi ... Biraz dil tonunu atarım. –

+1

Güncelleme için teşekkürler! – Joe

+1

Teşekkürler düşünüyorum bu mantıklı. Yarın deneyeceğim. Bununla birlikte, eğer makro2'nin değerleri veya makro değişkenleri alabilecek kadar genel olamayacağı anlamına gelip gelmediğini merak ediyorum. Yukarıda yazıldığı gibi, şimdi sadece makro değişkenler almakla sınırlıdır? – DanRoDuq

2

Sparc_Spread, SAS makro dilinde sorununuzu çözebilecek "referans olarak nasıl aranacağını" açıklar. Yine de bu özel durumda, bu, referans ile arama kullanmak için çok önemli değildir ve bunu kullanmak için SAS makro dilinin deyimsel olmadığını iddia etmem (her ne kadar yanlış bir şey olsa da) - sadece biraz garip görünüyor, ve gerçekten de yerel bir konsept olmadığından biraz daha zordur, ancak istenirse bu şekilde kullanılması kesinlikle kasıtlı olarak desteklenir). Bunu aşmanın iki yolu vardır, her ikisi de kullanımı çok kolaydır.

Her şeyden önce, arttırmak istediğiniz değişken ismini bildiğinizi ve başlangıç ​​değerinin tek ilginç şey olduğunu varsayalım. SAS makro dilinin kapsam belirleme, tam olarak sözcüksel kapsam belirleme ve tam olarak işlevsel olmayan bir şeyle, otomatik olarak zaten var olduğunda, en yerel kapsamda bulunan değişkeni kullanır (makro kullanarak bazı küçük uyarılar ile) kullanır. DOSUBL).

Yani bu beklendiği gibi çalışır:

Eğer & variable1 201 değerini almasını bekliyorsanız
%macro macro2(counter=); 
    %do variable1 =&counter. %to 200; 
    %if %sysfunc(mod(&variable1.,50))=0 %then %put &=variable1; 
    %end; 

%mend macro2; 

%macro macro1(); 
    %let variable1= 0; 
    %macro2(counter=&variable1.); 

    %put &=variable1; 
%mend macro1; 

%macro1; 

(Tabii, yani - %do döngüler, do döngüler gibi, her zaman daha yüksek bir artırılır olsun çünkü onların . değerini biten keşke gerçek prosedür farklı çalışır varsayıyorum)

&variable1. %macro2 atıfta çünkü var

otomatik olarak en yerel kapsamında bir mevcut -. Bu durumdakapsamı olan 0. Bir sayıcı amacıyla bu %macro2 kullanıyorsanız


Alternatif, ben function-style macro yöntemini kullanırsınız.

Tanım gereği bir işlev stili makrosu, yalnızca tek bir değer döndüren birdir - ve returns ile düz metinde sunulan makronun kodunun sonunda tek bir değere sahiptir. , sadece normal SAS dil ayrıştırıcısı tarafından ayrıştırılacak bir metin oluşturmayı amaçlamaktadır).

Bu, daha sonra bir atama bildirisinde eşit bir işaretin sağ tarafında kullanılabilir. Anahtar, yalnızca makro dil öğelerini - %do döngüler ve benzeri - ve hiçbir veri adımı, proc, vb., Atama deyiminde eşit bir işaretin sağ tarafında olmasını engelleyecek dil kullanmamasıdır (ör. x=%macrostuff();x=proc sql(select...)).

Böylece, aşağıdakiler hedefe ulaşır: bir sayacı bir miktar artırır, değeri (201, bu durumda, daha önce olduğu gibi) döndürür ve sonra bir makro değişkenine atanabilir.

bu Bunu gerçekleştirmek için en deyimsel yolu ve en basit öneririm

%macro macro2(counter=); 
    %do internal_counter =&counter. %to 200; 
    %if %sysfunc(mod(&internal_counter.,50))=0 %then %put &=internal_counter.; 
    %end; 
    &internal_counter. 
%mend macro2; 

%macro macro1(); 
    %let variable1= %macro2(counter=0); 

    %put &=variable1; 
%mend macro1; 

%macro1; 
: Eğer girdi olarak istediğiniz değeri geçmesi, fonksiyon üzerinde çalışır, sonra bir değişkene atamak değerini döndürür Ancak makronuzda istersiniz.

+0

+1 bu da sorunu çözüyor. '& =' Sözdizimini hiç bilmiyordum! Hata ayıklama vb. Için çok yararlı. Bu her zaman SAS'ta mıydı? Mor Carpenter kitabını çok defa okudum ve hiç karşılaştığımı sanmıyorum. –

+1

'& =' 9.3’ten itibaren yeni (ya da belki de 9.2) bence - güzel bir küçük ayar! – Joe

+0

Kesinlikle öyle. Gönderin için teşekkürler! –