2013-02-12 4 views
0

Вот код макроса .....Как я могу выполнить макрос для каждого наблюдения в sas-наборе данных?

libname myfmt "&FBRMrootPath./Formats"; 
%macro CreateFormat(DSN,Label,Start,fmtname,type); 
options mprint mlogic symbolgen; 
%If &type='n' %then %do; 
    proc sort data=&DSN out=Out; by &Label; 
     Run; 
    Data ctrl; 
     set Out(rename=(&Label=label &Start=start)) end=last; 
     retain fmtname &fmtname type &type; 
     output; 
    If last then do; 
     hlo='O'; 
     label='*ERROR'; 
     output; 
    End; 
Run; 
%End; 
%Else %do; 
    proc sort data=&DSN out=Out; by &Start; 
     Run; 
    Data ctrl; 
     set Out(rename=(&Start=label &Label=start)) end=last; 
     retain fmtname &fmtname type &type; 
     output; 
    If last then do; 
     hlo='O'; 
     label='*ERROR'; 
     output; 
    End; 
Run; 
%End; 
proc format library=myfmt cntlin=ctrl; 
Run; 
%Mend CreateFormat; 

Вот код для управляющих данных, установленных с помощью которых выше макрос должен запустить для каждого наблюдения набора данных и значения наблюдений являются входами для varibales в макрорезист ...

Data OPER.format_control; 
Input DSN :$12. Label :$15. Start :$15. fmtName :$8. type :$1. fmt_Startdt :mmddyy. fmt_Enddt :mmddyy.; 
format fmt_Startdt fmt_Enddt date9.; 
Datalines; 
ssin.prd prd_nm prd_id mealnm n . 12/31/9999 
ssin.prd prd_id prd_nm mealid c . 12/31/9999 
ssin.fac fac_nm onesrc_fac_id fac1SRnm n . 12/31/9999 
ssin.fac fac_nm D3_fac_id facD3nm n . 12/31/9999 
ssin.fac onesrc_fac_id D3_fac_id facD31SR n . 12/31/9999 
oper.wrkgrp wrkgrp_nm wrkgrp_id grpnm n . 12/31/9999 
; 

ответ

0

Нечто подобное.

proc sql; 
select catx(',',cats('%CreateFormat(',DSN),Label,Start,fmtname,cats(type,')'); 
into :formcreatelist separated by ' ' 
from oper.format_control; 
quit; 

Возможно, вам потребуется указать некоторые из ваших переменных, чтобы получить желаемый формат в макропеременной. Я использую немного cludgy cats/catx combo здесь, вы могли бы кошки раз с ',' добавлен в кучу раз также.

У вас есть предел здесь - всего около 20 000 символов в макропеременной. Если это закончилось, вам либо нужно использовать CALL EXECUTE (у которого есть некоторые причудливые функции), либо вы можете поместить вызов макроса в текстовый файл и% INCLUDE.

0

Существует лучший способ сделать это, а не выбирать ... в макропеременной. Используйте временный файл, подобный этому:

Этот метод не ограничен ограничением длины 32k для макропеременных.

Обратите внимание, что вы обязательно должны использовать одинарные кавычки вокруг% createformat, чтобы предотвратить запуск SAS макроса непосредственно перед компиляцией шага данных. Вы хотите, чтобы макрос запускался при запуске% include.

Вышеупомянутый подход аналогичен вызову execute, но вызов execute является злым, потому что он не выполняет макрокоманду и внедренный код данных/proc внутри макроса в ожидаемом порядке. Избегайте выполнения вызова.

И, наконец, если вы используете интерактивный SAS и используя технику, вы можете использовать аккуратный трюк, который вы можете использовать для отладки. Прокомментируйте последние две строки кода - четкое указание и имя файла. После запуска оставшегося кода введите команду SAS «fslist dyncode» в окне команд. Появится надпись на динамическом коде, который вы только что создали. Вы можете просмотреть его и убедиться, что у вас есть то, что вы намеревались.

+0

Я отправил пример вызова выполнить решение. Будет ли это выполнять итерации макроса в другом порядке от вашего решения? – user667489

+0

Выполнение вызова выполняется в шагах макросов в правильном порядке в вашем решении. Так что не беспокойтесь. Тем не менее, простой факт, что вызов execute будет * иногда * запускаться в неожиданном порядке, страшен мне, и теперь я избегаю его исключительно на принципе. Вот статья, в которой обсуждается эта проблема: http://www2.sas.com/proceedings/sugi22/CODERS/PAPER70.PDF См. Раздел «Пример вызова макроса» на стр. 2/3. –

0

Вот вызов выполнить решение, только для полноты:

data _null_; 
    set OPER.format_control; 
    call execute('%CreateFormat(' || DSN || ',' || Label || ',' || Start || ',' || fmtname || ',' || type || ');'); 
run;