2015-06-18 4 views
0

Я пытаюсь использовать макрос PARMBUFF, чтобы повторить шаг данных с 20 различными определениями клиентов (один пример ниже).Имя/название макроса как переменной внутри макроса SAS

DATA _NULL_; 
%GLOBAL bank1; 
%LET bank1 = O.OWNER LIKE 'XXXXX%'; 
RUN; 

Шаг данных создает отдельные таблицы, определенные макросами клиента, которые создаются выше.

%MACRO CLIENTBUILD/PARMBUFF; 
%LET N=%SYSFUNC(COUNTW(&SYSPBUFF,%STR(,))); 
%DO I=1 %TO &N; 
    %LET CLIENT=%SCAN(%QSYSFUNC(COMPRESS(%BQUOTE(&SYSPBUFF),%STR(%(%)))),&I,%STR(,)); 
CREATE TABLE CLIENT AS 
SELECT DISTINCT C.DATE, 
      C.TIME, 
      C.RELEASE, 
      C.TASK 
FROM CALLS C 
INNER JOIN OWN_GRNT O ON SUBSTR(C.TASK,1,9)= O.TASK 
AND &CLIENT 
; 
%END; 
%MEND; 

Я хотел бы создать эту таблицу с именем (String) макрокоманды ... но у меня возникают проблемы, ссылающихся строку макроса для имени таблицы. Я пытался переформатировать макрос следующим образом (для того, чтобы попытаться взывать строку/имя макроса для имени таблицы) с помощью

%MACRO CLIENTBUILD/PARMBUFF; 
%LET N=%SYSFUNC(COUNTW(&SYSPBUFF,%STR(,))); 
%DO I=1 %TO &N; 
    %LET CLIENT=%SCAN(%QSYSFUNC(COMPRESS(%BQUOTE(&SYSPBUFF),%STR(%(%)))),&I,%STR(,)); 
CREATE TABLE '&CLIENT' AS 
SELECT DISTINCT C.DATE, 
       C.TIME, 
       C.RELEASE, 
       C.TASK 
FROM CALLS C 
INNER JOIN OWN_GRNT O ON SUBSTR(C.TASK,1,9)= O.TASK 
AND &CLIENT 
; 
%END; 
%MEND; 
Then calling the macro out with – 
PROC SQL; 
%CLIENTBUILD(&NCT); 
QUIT; 

Но это приводит к ошибке:

ERROR: The value &CLIENT is not a valid SAS name.` 

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

Proc SQL; 

%CLIENTBUILD(&bank1,&bank2,&bank3,..........); 

QUIT; 
+0

Удалить одинарные кавычки вокруг & CLIENT - как в 'CREATE TABLE & client AS ...' Одиночные кавы маскируют переменную & CLIENT от разрешения. Таблицы SAS не могут начинаться с '&', и это дает вам ошибку. – DomPazz

+0

Проблема с этим заключается в том, что она решит фактическое определение макроса (O.OWNER LIKE 'XXXXX%') вместо имени - «bank1» ... Я хочу, чтобы он разрешался внизу в «WHERE & CLIENT», (ошибка в исходном сообщении ... вместо AND и CLIENT) и использовать строку (bank1) в качестве имени таблицы ... – SMW

+1

Используйте макрокоманду (например, '% nrstr') для управления разрешением. И если вы хотите, чтобы 'bank1' не' & bank1', у вас возникнут трудности, потому что это не так, как работают макро переменные SAS. Вам нужно будет пересмотреть подход здесь - в частности, похоже, что вы должны передать два параметра, а не один. – Joe

ответ

3

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

Написать макрос этого путь:

%macro maketable(table=,where=); 
    proc sql; 
    create table &table. as 
     ... 
     where &where.; 
    quit; 
%mend maketable; 

И затем построить вызовы %maketable из набора данных, который хранит ваш ИНЕК (я предполагаю, что это не просто открыть код Если да, то помести его в наборе данных с помощью? первенствовать или что-то.)

proc sql; 
    select cats('%maketable(table=',tablename,',where=%nrstr(',whereclause,'))' 
    into :tablecall separated by ' ' 
    from my_whereclause; 
quit; 

а потом просто включить &tablecall. на следующей строке и при запуске, вы получите все ваши таблицы.

(В стороне, скорее всего, вы, возможно, даже не можете сделать 20 таблиц, но сделайте 1 таблицу с 20 значениями переменной, но вы не объясните, что вы делаете после этого, так что это сложно чтобы сообщить.)


Если вы должны сделать это таким образом, вам нужно понять, как работает изменение макропеременной. См. my answer here для получения какого-либо объяснения, или my SGF paper по этому вопросу. Документация SAS также неплохо объясняет это.

В принципе, вам нужно разрешить имя вашей таблицы &table, чтобы определить имя таблицы, а затем несколько разрешить ее, чтобы получить предложение where.

Вот пример использования sashelp.class.

%let abc= age gt 13; 
%let def= age lt 13; 
%let ghi= age eq 13; 
%macro doit/parmbuff; 
    %LET N=%SYSFUNC(COUNTW(&SYSPBUFF,%STR(,))); 
    %DO I=1 %TO &N; 
     %LET CLIENT=%SCAN(%QSYSFUNC(COMPRESS(%BQUOTE(&SYSPBUFF),%STR(%(%)))),&I,%STR(,)); 
     %PUT &=CLIENT; 

     proc sql; 
     create table &client. as 
      select * from sashelp.class 
      where &&&client.; 
     quit; 
    %end; 
%mend doit; 

%doit(abc,def,ghi); 

&&&client решает &client к abc, затем покидает амперсанд там (так &abc) - и затем решает, что, таким образом это решает &abc к своему значению (где положение).

+0

Дал вам чек ... в конце всего, отступив назад и перестроив (программа и макроструктура), было решение . А что касается вашего предложения о создании дополнительного набора данных, содержащего все переменные ... открыла некоторую гибкость. Большое вам спасибо! – SMW

0

Вам не нужно использовать PARMBUFF для этого типа приложений. Просто не используйте запятую в качестве разделителя. Например, вы можете использовать пробелы или | как в примере ниже.

%macro doall(list); 
    %local i item ; 
    %do i=1 %to %sysfunc(countw(&list,|)); 
    %let item=%scan(&list,&i,|); 
    ... process current item ... 
    %end; 
%mend doall ; 
%doall(A|B|C|D);