2016-09-26 7 views
-1

ライブラリに2つのデータセットがあります。それぞれ&bbです。 私のコードは、特定の列変数を持つライブラリのデータセットを最初にチェックします。データセットに特定の変数がある場合は、それらが追加されます。 しかし、マクロを実行すると、ライブラリのデータセットがチェックされません。&はtest1に値を追加します。& test2これは変数に変数が含まれている場合、データセットをチェックする目的の機能を実行しません。エラー& ds &リストのためのシンボリックリファレンス&も& dsと&リストで構文エラーを示しています。ライブラリを検索して特定の変数を持つデータセットを追加する

は、あなたが任意の編集を提案するだろうことができます...以下

は私のコード..です

%macro CHK(lib1=,lib2=,varlist=); 

%local 
list 
ds 
; 

    proc sql noprint; 
    select distinct catx(".",libname,memname) into :list separated by " " 
     from dictionary.columns 
     where libname = %upcase ("&lib1") and %upcase(name) in("&varlist") ; 
    quit; 
%put &list; 

    data test1; 
    set &list; 
    run; 

    proc sql noprint; 
    select distinct catx(".",libname,memname) into :ds separated by " " 
     from dictionary.columns 
     where libname = %upcase ("&lib2") and %upcase(name) in("&varlist") ; 
    quit; 

%put &ds; 

data test2; 
set &ds; 
run; 

%mend CHK; 

%CHK(lib1=aa,lib2=bb,varlist=%str('nam', 'DD', 'ht')); 
+0

をから期待される出力を含めるようにあなたの質問を編集してくださいあなたが投稿した例とあなたが試したコード。 – Quentin

+0

質問を編集したので、今は本当に新しい質問だと思います。私はその質問を理解していません。以前のバージョンを復元し、新しい質問を追加することをお勧めします。 – Quentin

+0

これも、元々あなたが質問したのとは異なる質問です。それは新しい質問でなければなりません。あなたは私が答えた元の質問を元に戻し、これを新しい質問にするべきです。つまり、WHERE文を次のように変更してみてください: 'libname =%upcase("&lib1 ")とupcase(name)in(%upcase(&varlist)); ' – Quentin

答えて

1

私は3段階のプロセスとしてそれを参照してください。

  1. は、リストを取得します変数を持つライブラリ内のデータセットの数。
  2. PROC FORMATをCNTLINデータセットとして読み取ることができる構造内で、変数の一意の値のデータセットを作成し、各値をシーケンシャルコードにマップする形式を作成します。
  3. 変数をコード化する形式を使用して、各データセットを処理します。ここで

は、いくつかのサンプルコードです:あなたのサンプルデータで

%macro Recode(lib=,var=); 

%local 
    DataList 
    i 
    data_i 
; 

%*1. Get a list of datasets in the library that have the variable; 

proc sql noprint ; 
    select distinct catx(".",libname,memname) into :DataList separated by " " 
    from dictionary.columns 
    where libname = %upcase("&lib") and upcase(name) = %upcase("&var"); 
quit; 

%put >>&DataList<<; 

%*2. Read the unique values of the variable into a dataset 
    and then create a format named $recode that maps each unique value 
    to a sequential code. 
; 

proc sql; 
    create table __cntlin as 
    select "$Recode" as fmtname, &var as start, put(monotonic(),z6.) as label 
    from 
     (
     %do i=1 %to %sysfunc(countw(&datalist,%str())); 
     %let data_i=%scan(&datalist,&i,%str()); 
     %if &i>1 %then union; 
     select &var from &data_i 
     %end; 
    ) 
    ; 
quit; 

proc format cntlin=__cntlin 
      library=work 
      fmtlib 
    ; 
    select $recode; 
run; 

%*3. Use the format to recode the variable in each dataset; 

%do i=1 %to %sysfunc(countw(&datalist,%str())); 
    %let data_i=%scan(&datalist,&i,%str()); 

    data &data_i._R; 
    set &data_i; 
    &var._R=put(&var,$recode.); 
    run; 
%end; 


*Cleanup; 
proc catalog cat=work.formats; 
    delete Recode.formatc; 
quit; 
proc datasets library=work memtype=data nolist; 
    delete __cntlin; 
quit; 

%mend Recode; 

%Recode(lib=work,var=name) 

、上記のコードは、2つのデータセットTest1_RとTest2_R生成:

1454 data _null_; 
1455 set Test1_R; 
1456 put @1 Name @10 Name_R; 
1457 run; 

sam  000006 
danny 000003 
jacob 000004 
susan 000009 
sandra 000007 
vinny 000010 
alicia 000001 
NOTE: There were 7 observations read from the data set WORK.TEST1_R. 

1458 
1459 data _null_; 
1460 set Test2_R; 
1461 put @1 Name @10 Name_R; 
1462 run; 

sam  000006 
dann  000002 
jhon  000005 
susan 000009 
sandy 000008 
vinny 000010 
NOTE: There were 6 observations read from the data set WORK.TEST2_R. 
+0

おそらくループを変更することで可能です。たとえば、パート3では、見つかったすべてのデータセットのリストをループする代わりに、入力データセットとユーザーがパラメータとして提供する出力データセットのリストをループします。 – Quentin

+0

lib =パラメータはライブラリ名を渡す必要があります。マクロの外側で、libname文を使用して、データセットを持つディレクトリを指すlibrefを作成します。書かれているように、私は推測している&datalistはnullです。セクション1の最後の%putステートメントに値が表示されます。 – Quentin

+0

マクロの外に 'libname mylib" d:\ datafolder ";"を追加して、その中にあなたのデータセットを持つディレクトリをポンドするライブラリを作成します。 – Quentin

関連する問題