1

素人なので語彙力が乏しいのは許してください!

%macro wtv(n);
var&n = 1;
%mend; 

do while (n < 10);
n+1;
%wtv(n); /*here's the problem I think*/
end;

nアイデアは次のとおりです。マクロ入力 (コメントがある場所) で使用したいと思います。コードは明らかに単純化された例にすぎません。これは私がやりたいこととはまったく異なりますが、アイデアはわかります! nマクロを呼び出すときに変数 (たとえば)を使用するにはどうすればよいですか? 今書いたコードは文字として n を使用し、 , , ...varn = 1の代わりに, を返します。var1 = 1var2 = 1var3 = 1var9 = 1

本当にありがとう!

4

2 に答える 2

3

アマチュアとして、最初に理解する必要があるのは、マクロのいくつかのルールです。

  1. マクロはテキスト/コードを出力します。
  2. マクロは、コードが実行/コンパイル/送信される前に動作します。
  3. 「マクロランド」と「データステップランド」の内容を常に把握するように心がけてください。「マクロ ランド」のすべてが最初に計算されるため、その結果が出力され、「データ ステップ ランド コード」として実行されます。マクロで「データ ステップ ランド」から変数を参照しようとすると、マクロが「データ ステップ ランド」を認識しない/参照できないため、問題が発生します。

では、あなたの例では何が間違っているのでしょうか?

「do while」ループはデータステップランドにあります。「%wtv(n)」はマクロ ランドにあり、データ ステップ コードの前に実行されます。

マクロは、入力テキスト「n」をパラメーターとして認識し、忠実に次のように書き出します。

varn = 1; 

テキスト「n」がマクロ変数「&n」の値として入力されたため、n が &n に置き換えられました。Macro land の操作は終了し、残っているコードは次のようになります。

do while (n < 10);
n+1;
varn = 1;
end;

このコードは忠実に実行されますが、「varn = 1;」です。while ループの各反復を通じて同じままになりますが、これはおそらくあなたが望んでいたことではありません。

それで、あなたは何をしたいですか?コードを使用して n でインデックス付けされた変数をループする場合は、提案された Hong Ooi の応答のような配列を使用します。通常、通常のコードで十分な場合は、マクロを使用しないことをお勧めします。

しかし、何らかの生産的な理由で実際にマクロ ループ マジックを使用したい場合があります。それは起こります。その場合は、データ ステップの "do while" ループではなく、代わりにマクロ ループが必要になる場合があります。このような場合、wtv マクロは次のようになります。

%macro wtv(n);
%local i;  /* explicit declarations are a good habit to get into */
%let i = 1;
%do %while (&i <= &n); 
var&i = 1;
%let i = %eval(&i + 1);
%end;
%mend wtv;  /* explicitly named mend statements are also good */ 

これで、%wtv(5) を呼び出すことができ、データ ステップ コードに解決されるはずです。

var1 = 1;
var2 = 1;
var3 = 1;
var4 = 1;
var5 = 1;

適切な数値を入力してデータ ステップに含める必要があるだけですが、欠点は、データ ステップ変数を参照せずにこれを行う必要があることです。マクロはデータ ステップの前に実行されるため、実行時にデータ ステップから派生した情報を使用して独自の操作を実行することはできません。

コードを書いているときにこの番号をすでに知っていれば、準備は完了です。このような場合、データ ステップの "do while" ループや配列はまったく必要ありません。

于 2013-08-10T00:23:04.610 に答える
2

これにはマクロは必要ありません。代わりに配列を使用してください。

data;
    array var{9} var1-var9;
    do i=1 to 9;
       var{i} = 1;
    end;
    ...

実際、ループも必要ありません。arrayステートメントで変数を直接初期化できます。

    array var{9} var1-var9 (9*1);
于 2013-08-09T22:13:29.780 に答える